From a59c70948f14a16db320a30d0350fb1a7e3b6f74 Mon Sep 17 00:00:00 2001 From: derekllanes Date: Mon, 27 Apr 2026 23:51:21 -0400 Subject: [PATCH 1/3] Fix Ticket 378: Add banner for optional input tracks --- src/media/MediaDisplayComponent.cpp | 39 +++++++++++++++++++++++++++++ src/media/MediaDisplayComponent.h | 1 + 2 files changed, 40 insertions(+) diff --git a/src/media/MediaDisplayComponent.cpp b/src/media/MediaDisplayComponent.cpp index 7d9c9023..b42b38ff 100644 --- a/src/media/MediaDisplayComponent.cpp +++ b/src/media/MediaDisplayComponent.cpp @@ -315,10 +315,49 @@ void MediaDisplayComponent::paint(Graphics& g) } } +void MediaDisplayComponent::paintOverChildren(Graphics& g) +{ + // Detect optional AND input track AND not a thumbnail + if (!isRequired() && isInputTrack() && !isThumbnailTrack()) + { + // Grab that 24-pixel vertical slice on the far left that we reserved in resized() + auto bannerArea = getLocalBounds().removeFromLeft(24); + + // Draw the solid orange background + g.setColour(Colours::darkorange); + g.fillRect(bannerArea); + + // Setup text formatting + g.setColour(Colours::white); + g.setFont(12.0f); + + // Save the graphics state before rotating + Graphics::ScopedSaveState state(g); + + // Rotate the graphics context -90 degrees around the center of our banner + float cx = static_cast(bannerArea.getCentreX()); + float cy = static_cast(bannerArea.getCentreY()); + g.addTransform(AffineTransform::rotation(-MathConstants::halfPi, cx, cy)); + + // Create a rotated bounding box for the text + Rectangle textBounds(0, 0, static_cast(bannerArea.getHeight()), static_cast(bannerArea.getWidth())); + textBounds.setCentre(cx, cy); + + // Draw the text inside our rotated box + g.drawText("OPTIONAL INPUT TRACK", textBounds, Justification::centred, false); + } +} + void MediaDisplayComponent::resized() { Rectangle totalBounds = getLocalBounds(); + // Reserve 24 pixels on the left edge for the vertical "Optional Input" banner. + if (!isRequired() && isInputTrack() && !isThumbnailTrack()) + { + totalBounds.removeFromLeft(24); + } + // Remove existing items in main flex mainFlexBox.items.clear(); diff --git a/src/media/MediaDisplayComponent.h b/src/media/MediaDisplayComponent.h index 39b91e58..7e4c9a84 100644 --- a/src/media/MediaDisplayComponent.h +++ b/src/media/MediaDisplayComponent.h @@ -79,6 +79,7 @@ class MediaDisplayComponent : public Component, virtual StringArray getInstanceExtensions() = 0; void paint(Graphics& g) override; + void paintOverChildren(Graphics& g) override; virtual void resized() override; void repositionLabels(); From 8f6649758d52d3abe3f982e9d3c4e053c5b72206 Mon Sep 17 00:00:00 2001 From: derekllanes Date: Fri, 8 May 2026 13:46:51 -0400 Subject: [PATCH 2/3] Refine optional input banner text and color --- src/media/MediaDisplayComponent.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/media/MediaDisplayComponent.cpp b/src/media/MediaDisplayComponent.cpp index b42b38ff..5444deef 100644 --- a/src/media/MediaDisplayComponent.cpp +++ b/src/media/MediaDisplayComponent.cpp @@ -323,8 +323,8 @@ void MediaDisplayComponent::paintOverChildren(Graphics& g) // Grab that 24-pixel vertical slice on the far left that we reserved in resized() auto bannerArea = getLocalBounds().removeFromLeft(24); - // Draw the solid orange background - g.setColour(Colours::darkorange); + // Draw the background color + g.setColour(Colour::fromRGB(90, 105, 105)); g.fillRect(bannerArea); // Setup text formatting @@ -344,7 +344,7 @@ void MediaDisplayComponent::paintOverChildren(Graphics& g) textBounds.setCentre(cx, cy); // Draw the text inside our rotated box - g.drawText("OPTIONAL INPUT TRACK", textBounds, Justification::centred, false); + g.drawText("OPTIONAL", textBounds, Justification::centred, false); } } @@ -352,7 +352,7 @@ void MediaDisplayComponent::resized() { Rectangle totalBounds = getLocalBounds(); - // Reserve 24 pixels on the left edge for the vertical "Optional Input" banner. + // Reserve 24 pixels on the left edge for the vertical "Optional" banner. if (!isRequired() && isInputTrack() && !isThumbnailTrack()) { totalBounds.removeFromLeft(24); From 585f1f1ccf50345e154235ff28def617af149744 Mon Sep 17 00:00:00 2001 From: Frank Cwitkowitz Date: Fri, 15 May 2026 14:08:00 -0400 Subject: [PATCH 3/3] Adapted banner to current flexbox layout. --- src/media/MediaDisplayComponent.cpp | 72 +++++++++++++---------------- src/media/MediaDisplayComponent.h | 32 ++++++++----- 2 files changed, 53 insertions(+), 51 deletions(-) diff --git a/src/media/MediaDisplayComponent.cpp b/src/media/MediaDisplayComponent.cpp index 5444deef..2a1765b0 100644 --- a/src/media/MediaDisplayComponent.cpp +++ b/src/media/MediaDisplayComponent.cpp @@ -6,6 +6,27 @@ #include +void OptionalBannerComponent::paint(Graphics& g) +{ + const float cx = static_cast(getWidth()) / 2.0f; + const float cy = static_cast(getHeight()) / 2.0f; + + g.setColour(Colour::fromRGB(90, 105, 105)); + g.fillAll(); + + g.setColour(Colours::white); + g.setFont(12.0f); + + Graphics::ScopedSaveState state(g); + g.addTransform(AffineTransform::rotation(-MathConstants::halfPi, cx, cy)); + + Rectangle textBounds( + 0, 0, static_cast(getHeight()), static_cast(getWidth())); + textBounds.setCentre(cx, cy); + + g.drawText("OPTIONAL", textBounds, Justification::centred, false); +} + namespace { struct TickScheme @@ -164,6 +185,8 @@ MediaDisplayComponent::MediaDisplayComponent(String name, bool req, bool fromDAW horizontalScrollBar.setAutoHide(false); horizontalScrollBar.addListener(this); + addAndMakeVisible(optionalBanner); + timeAxisStrip = std::make_unique(this); mediaAreaContainer.addAndMakeVisible(overheadPanel); @@ -315,49 +338,10 @@ void MediaDisplayComponent::paint(Graphics& g) } } -void MediaDisplayComponent::paintOverChildren(Graphics& g) -{ - // Detect optional AND input track AND not a thumbnail - if (!isRequired() && isInputTrack() && !isThumbnailTrack()) - { - // Grab that 24-pixel vertical slice on the far left that we reserved in resized() - auto bannerArea = getLocalBounds().removeFromLeft(24); - - // Draw the background color - g.setColour(Colour::fromRGB(90, 105, 105)); - g.fillRect(bannerArea); - - // Setup text formatting - g.setColour(Colours::white); - g.setFont(12.0f); - - // Save the graphics state before rotating - Graphics::ScopedSaveState state(g); - - // Rotate the graphics context -90 degrees around the center of our banner - float cx = static_cast(bannerArea.getCentreX()); - float cy = static_cast(bannerArea.getCentreY()); - g.addTransform(AffineTransform::rotation(-MathConstants::halfPi, cx, cy)); - - // Create a rotated bounding box for the text - Rectangle textBounds(0, 0, static_cast(bannerArea.getHeight()), static_cast(bannerArea.getWidth())); - textBounds.setCentre(cx, cy); - - // Draw the text inside our rotated box - g.drawText("OPTIONAL", textBounds, Justification::centred, false); - } -} - void MediaDisplayComponent::resized() { Rectangle totalBounds = getLocalBounds(); - // Reserve 24 pixels on the left edge for the vertical "Optional" banner. - if (!isRequired() && isInputTrack() && !isThumbnailTrack()) - { - totalBounds.removeFromLeft(24); - } - // Remove existing items in main flex mainFlexBox.items.clear(); @@ -374,6 +358,16 @@ void MediaDisplayComponent::resized() { // Place header beside media mainFlexBox.flexDirection = FlexBox::Direction::row; + + if (! isRequired() && isInputTrack() && ! isThumbnailTrack()) + { + mainFlexBox.items.add(FlexItem(optionalBanner).withWidth(24)); + } + else + { + optionalBanner.setBounds(0, 0, 0, 0); + } + // Fixed area for track label and buttons mainFlexBox.items.add(FlexItem(headerComponent).withFlex(1).withMaxWidth(40).withMargin(4)); } diff --git a/src/media/MediaDisplayComponent.h b/src/media/MediaDisplayComponent.h index 7e4c9a84..7769861b 100644 --- a/src/media/MediaDisplayComponent.h +++ b/src/media/MediaDisplayComponent.h @@ -27,6 +27,23 @@ enum class DisplayMode Thumbnail // Reduced functionality }; +class OptionalBannerComponent : public Component +{ +public: + void paint(Graphics& g) override; +}; + +class TimeAxisStrip : public Component +{ +public: + explicit TimeAxisStrip(MediaDisplayComponent* ownerIn) : owner(ownerIn) {} + + void paint(Graphics& g) override; + +private: + MediaDisplayComponent* owner = nullptr; +}; + class ColorablePanel : public Component { public: @@ -48,17 +65,6 @@ class ColorablePanel : public Component Colour backgroundColor; }; -class TimeAxisStrip : public Component -{ -public: - explicit TimeAxisStrip(MediaDisplayComponent* ownerIn) : owner(ownerIn) {} - - void paint(Graphics& g) override; - -private: - MediaDisplayComponent* owner = nullptr; -}; - class MediaDisplayComponent : public Component, public ChangeListener, public ChangeBroadcaster, @@ -79,7 +85,6 @@ class MediaDisplayComponent : public Component, virtual StringArray getInstanceExtensions() = 0; void paint(Graphics& g) override; - void paintOverChildren(Graphics& g) override; virtual void resized() override; void repositionLabels(); @@ -273,6 +278,9 @@ class MediaDisplayComponent : public Component, MultiButton::Mode copyFileButtonActiveInfo; MultiButton::Mode copyFileButtonInactiveInfo; + // Banner shown on left edge of optional input tracks + OptionalBannerComponent optionalBanner; + // Panel displaying overhead labels ColorablePanel overheadPanel { overheadPanelColor };