gled-ui 2.31.1

gled's egui interface, shared by the desktop app and the browser
Documentation
use super::BUTTON_HEIGHT;
use crate::app::{App, client_timing::LINK_ACTIVE_COLOR};
use crate::ui::scoped_frame;
use egui::{Color32, Frame, Response, Stroke, Ui, UiBuilder, Vec2, Widget};
use epaint::{Margin, RectShape, StrokeKind};

pub(super) struct BpmBar<'a> {
    pub(super) app: &'a mut App,
}

impl Widget for BpmBar<'_> {
    fn ui(self, ui: &mut Ui) -> Response {
        let app = self.app;
        let link_read_only = app.server_settings().ableton_link_read_only;
        let rect = ui.available_rect_before_wrap();

        let resp = scoped_frame(
            ui,
            UiBuilder::default()
                .max_rect(rect)
                .layout(egui::Layout::right_to_left(egui::Align::Center)),
            Frame::new()
                .fill(Color32::from_gray(20))
                .inner_margin(Margin::symmetric(10, 0)),
            |ui| {
                // add background shadow
                ui.painter().add(
                    RectShape::filled(
                        ui.available_rect_before_wrap().expand(1.0),
                        ui.ctx().global_style().visuals.widgets.active.corner_radius,
                        Color32::from_white_alpha(10),
                    )
                    .with_blur_width(15.0),
                );

                app.timing
                    .tap_button(ui, Vec2::new(80.0, BUTTON_HEIGHT), link_read_only);
                app.timing.double_button(ui, link_read_only);
                app.timing.half_button(ui, link_read_only);

                ui.spacing_mut().slider_width = ui.available_width() - 80.0;
                app.timing.bpm_slider(ui, !link_read_only);
            },
        );
        ui.painter().vline(
            rect.left(),
            rect.top()..=rect.bottom(),
            ui.style().visuals.widgets.noninteractive.bg_stroke,
        );
        ui.painter().vline(
            rect.right(),
            rect.top()..=rect.bottom(),
            ui.style().visuals.widgets.noninteractive.bg_stroke,
        );
        if app.model.replica.state.status.link_peers > 0 {
            ui.painter().rect_stroke(
                rect,
                5.0,
                Stroke::new(1.0, LINK_ACTIVE_COLOR),
                StrokeKind::Outside,
            );
        }
        resp.response
    }
}