Skip to content

Commit

Permalink
Add initial explicit layout class. Add ruled label (#96)
Browse files Browse the repository at this point in the history
All part of starting to restructure the bus screens in SCXT but
useful for more than just that.
  • Loading branch information
baconpaul authored Jul 17, 2024
1 parent e700be8 commit 57d0860
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 1 deletion.
2 changes: 1 addition & 1 deletion include/sst/jucegui/components/Label.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ struct Label : public juce::Component, public style::StyleConsumer, public style

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Label)

private:
protected:
std::string text;
};
} // namespace sst::jucegui::components
Expand Down
95 changes: 95 additions & 0 deletions include/sst/jucegui/components/RuledLabel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* sst-jucegui - an open source library of juce widgets
* built by Surge Synth Team.
*
* Copyright 2023-2024, various authors, as described in the GitHub
* transaction log.
*
* sst-jucegui is released under the MIT license, as described
* by "LICENSE.md" in this repository. This means you may use this
* in commercial software if you are a JUCE Licensee. If you use JUCE
* in the open source / GPL3 context, your combined work must be
* released under GPL3.
*
* All source in sst-jucegui available at
* https://github.com/surge-synthesizer/sst-jucegui
*/

#ifndef INCLUDE_SST_JUCEGUI_COMPONENTS_RULEDLABEL_H
#define INCLUDE_SST_JUCEGUI_COMPONENTS_RULEDLABEL_H

#include <sst/jucegui/style/StyleAndSettingsConsumer.h>
#include <sst/jucegui/style/StyleSheet.h>

#include "Label.h"

namespace sst::jucegui::components
{
struct RuledLabel : public juce::Component,
public style::StyleConsumer,
public style::SettingsConsumer
{
struct Styles : base_styles::BaseLabel, base_styles::Outlined
{
using sclass = style::StyleSheet::Class;
using sprop = style::StyleSheet::Property;
static constexpr sclass styleClass{"label"};

static void initialize()
{
style::StyleSheet::addClass(styleClass)
.withBaseClass(base_styles::BaseLabel::styleClass)
.withBaseClass(base_styles::Outlined::styleClass);
}
};

RuledLabel() : style::StyleConsumer(Styles::styleClass) { setAccessible(true); };
~RuledLabel() = default;

void setText(const std::string &s)
{
text = s;
setTitle(s);
repaint();
}
std::string getText() const { return text; }

std::unique_ptr<juce::AccessibilityHandler> createAccessibilityHandler() override
{
return std::make_unique<juce::AccessibilityHandler>(*this, juce::AccessibilityRole::label);
}

void paint(juce::Graphics &g) override
{
g.setColour(getColour(Styles::labelcolor));
if (!isEnabled())
g.setColour(getColour(Styles::labelcolor).withAlpha(0.5f));
g.setFont(getFont(Styles::labelfont));
g.drawText(text, getLocalBounds(), juce::Justification::centred);

auto labelWidth = g.getCurrentFont().getStringWidth(text);

auto ht = getLocalBounds();
g.setColour(getColour(Styles::brightoutline));
auto q = ht.toFloat()
.withWidth((ht.getWidth() - labelWidth - 2) / 2)
.translated(0, ht.getHeight() / 2.f - 0.5)
.withHeight(1)
.withTrimmedRight(4);
g.fillRect(q);
q = ht.toFloat()
.withWidth((ht.getWidth() - labelWidth - 2) / 2)
.translated((ht.getWidth() - labelWidth - 2) / 2 + labelWidth + 2,
ht.getHeight() / 2.f - 0.5)
.withHeight(1)
.withTrimmedLeft(4);
g.fillRect(q);
}

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RuledLabel)

protected:
std::string text;
};
} // namespace sst::jucegui::components
#endif // SHORTCIRCUITXT_RULEDLABEL_H
110 changes: 110 additions & 0 deletions include/sst/jucegui/layouts/ExplicitLayout.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* sst-jucegui - an open source library of juce widgets
* built by Surge Synth Team.
*
* Copyright 2023-2024, various authors, as described in the GitHub
* transaction log.
*
* sst-jucegui is released under the MIT license, as described
* by "LICENSE.md" in this repository. This means you may use this
* in commercial software if you are a JUCE Licensee. If you use JUCE
* in the open source / GPL3 context, your combined work must be
* released under GPL3.
*
* All source in sst-jucegui available at
* https://github.com/surge-synthesizer/sst-jucegui
*/

#ifndef INCLUDE_SST_JUCEGUI_LAYOUTS_EXPLICITLAYOUT_H
#define INCLUDE_SST_JUCEGUI_LAYOUTS_EXPLICITLAYOUT_H

#include <juce_gui_basics/juce_gui_basics.h>
namespace sst::jucegui::layout
{
struct ExplicitLayout
{
static constexpr int labelHeight{18};
static constexpr int toggleSize{14};

ExplicitLayout() {}

struct NamedPosition
{
NamedPosition() {}
NamedPosition(const std::string &n) : name(n) {}

NamedPosition at(const juce::Rectangle<float> &t)
{
auto res = *this;
res.rect = t;
return res;
}

// Fractionally scale the 0...1 x and 0...h/w y
NamedPosition scaled(const juce::Rectangle<int> &into, float x, float y, float w, float h)
{
auto res = *this;
res.rect = juce::Rectangle<float>(into.getX() + x * into.getWidth(),
into.getY() + y * into.getWidth(),
w * into.getWidth(), h * into.getWidth());
return res;
}
NamedPosition scaled(const juce::Rectangle<int> &into, float x, float y, float w)
{
return scaled(into, x, y, w, w);
}

std::string name;
juce::Rectangle<float> rect{};
};
void addNamedPosition(const NamedPosition &n) { positions[n.name] = n; }
void addNamedPositionAndLabel(const NamedPosition &n)
{
addNamedPosition(n);
addLabelPositionTo(n.name);
}
void addPowerButtonPositionTo(const std::string &name, int w = toggleSize, int off = -1)
{
auto op = positionFor(name);
auto oh = op.getHeight();
op = op.withTrimmedLeft(op.getWidth() - w).withTrimmedBottom(op.getHeight() - w);
if (off < 0)
off = w / 4;
op = op.translated(off, -off);
addNamedPosition(NamedPosition(name + ".power").at(op.toFloat()));
}
void addLabelPositionTo(const std::string &name)
{
auto op = positionFor(name);
auto oh = op.getHeight();
op = op.withBottom(op.getBottom() + 18).withTrimmedTop(oh);
addNamedPosition(NamedPosition(name + ".label").at(op.toFloat()));
}

juce::Rectangle<int> positionFor(const std::string &s) const
{
auto p = positions.find(s);
if (p == positions.end())
{
std::cout << "Unable to find name " << s << std::endl;
assert(false);
return {};
}
return p->second.rect.toNearestIntEdges();
}

juce::Rectangle<int> labelPositionFor(const std::string &s) const
{
return positionFor(s + ".label");
}

juce::Rectangle<int> powerButtonPositionFor(const std::string &s) const
{
return positionFor(s + ".power");
}

std::unordered_map<std::string, NamedPosition> positions;
};
} // namespace sst::jucegui::layout

#endif // SHORTCIRCUITXT_EXPLICITLAYOUT_H
2 changes: 2 additions & 0 deletions src/sst/jucegui/style/StyleSheet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <sst/jucegui/components/WindowPanel.h>
#include <sst/jucegui/components/SevenSegmentControl.h>
#include <sst/jucegui/components/Label.h>
#include <sst/jucegui/components/RuledLabel.h>
#include <sst/jucegui/components/VUMeter.h>
#include <sst/jucegui/components/JogUpDownButton.h>
#include <sst/jucegui/components/ToolTip.h>
Expand Down Expand Up @@ -584,6 +585,7 @@ void StyleSheet::initializeStyleSheets(std::function<void()> userClassInitialize
n::NamedPanel::Styles::initialize();
n::NamedPanelDivider::Styles::initialize();
n::Label::Styles::initialize();
n::RuledLabel::Styles::initialize();
n::GlyphPainter::Styles::initialize();
n::WindowPanel::Styles::initialize();

Expand Down

0 comments on commit 57d0860

Please sign in to comment.