Skip to content

Commit e9c08b1

Browse files
committed
Design improvements: make DSP status more legible, make popupmenu items slightly taller, add labels and bigger hitboxes to canvas popup menu, make keyboard shortcut icons clearer
1 parent 1a2ed18 commit e9c08b1

6 files changed

Lines changed: 93 additions & 69 deletions

File tree

Resources/Fonts/IconFont.ttf

832 Bytes
Binary file not shown.

Source/Dialogs/Dialogs.cpp

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -502,85 +502,109 @@ void Dialogs::showCanvasRightClickMenu(Canvas* cnv, Component* originalComponent
502502

503503
struct QuickActionsBar : public PopupMenu::CustomComponent {
504504
struct QuickActionButton : public TextButton {
505-
explicit QuickActionButton(String const& buttonText)
506-
: TextButton(buttonText)
505+
QuickActionButton(String const& icon, String const& label)
506+
: TextButton(label)
507+
, iconGlyph(icon)
507508
{
508509
}
509510

511+
int getPreferredWidth() const
512+
{
513+
auto const font = Fonts::getDefaultFont().withHeight(11.0f);
514+
auto const textWidth = Fonts::getStringWidth(getButtonText(), font);
515+
return static_cast<int>(std::ceil(textWidth)) + 2;
516+
}
517+
510518
void paint(Graphics& g) override
511519
{
512520
auto const& colours = getThemeColours(*this);
513-
514521
auto textColour = colours.sidebarTextColour;
515522

516523
if (!isEnabled()) {
517524
textColour = textColour.withAlpha(0.35f);
518525
} else if (isOver() || isDown()) {
519-
auto bounds = getLocalBounds().toFloat();
520-
bounds = bounds.withSizeKeepingCentre(bounds.getHeight(), bounds.getHeight());
521-
522526
g.setColour(colours.popupMenuActiveBackgroundColour);
523-
g.fillRoundedRectangle(bounds, Corners::defaultCornerRadius);
524-
525-
textColour = colours.sidebarTextColour;
527+
g.fillRoundedRectangle(getLocalBounds().toFloat(), Corners::defaultCornerRadius);
526528
}
527529

528-
Fonts::drawIcon(g, getButtonText(), std::max(0, getWidth() - getHeight()) / 2, 0, getHeight(), textColour, 12.8f);
530+
Fonts::drawIcon(g, iconGlyph, 6, -2, getWidth() - 12, textColour, 15);
531+
532+
auto const labelBounds = Rectangle<int>(0, 22, getWidth(), 20);
533+
g.setFont(Fonts::getDefaultFont().withHeight(11));
534+
g.setColour(textColour);
535+
g.drawText(getButtonText(), labelBounds, Justification::centred, false);
529536
}
537+
538+
private:
539+
String iconGlyph;
530540
};
531541

532542
explicit QuickActionsBar(PluginEditor* editor)
533543
{
534-
auto commandIds = StackArray<CommandID, 5> { CommandIDs::Cut, CommandIDs::Copy, CommandIDs::Paste, CommandIDs::Duplicate, CommandIDs::Delete };
544+
auto const commandIds = StackArray<CommandID, 5> {
545+
CommandIDs::Cut,
546+
CommandIDs::Copy,
547+
CommandIDs::Paste,
548+
CommandIDs::Duplicate,
549+
CommandIDs::Delete
550+
};
535551

536552
int index = 0;
537-
for (auto* button : StackArray<QuickActionButton*, 5> { &cut, &copy, &paste, &duplicate, &remove }) {
553+
for (auto* button : getButtons()) {
538554
addAndMakeVisible(button);
539-
auto const id = commandIds[index];
555+
auto const id = commandIds[index++];
540556

541557
button->setCommandToTrigger(&editor->commandManager, id, false);
542558

543559
if (auto* registeredInfo = editor->commandManager.getCommandForID(id)) {
544560
ApplicationCommandInfo info(*registeredInfo);
545561
editor->commandManager.getTargetForCommand(id, info);
562+
546563
bool const canPerformCommand = (info.flags & ApplicationCommandInfo::isDisabled) == 0;
547564
button->setEnabled(canPerformCommand);
548565
} else {
549566
button->setEnabled(false);
550567
}
551-
index++;
552568
}
553-
554-
cut.setTooltip("Cut");
555-
copy.setTooltip("Copy");
556-
paste.setTooltip("Paste");
557-
duplicate.setTooltip("Duplicate");
558-
remove.setTooltip("Delete");
559569
}
560570

561571
void getIdealSize(int& idealWidth, int& idealHeight) override
562572
{
563-
idealWidth = 130;
564-
idealHeight = 26;
573+
int buttonWidth = 32;
574+
for (auto* button : getButtons())
575+
buttonWidth = std::max(buttonWidth, button->getPreferredWidth());
576+
577+
idealWidth = buttonWidth * 5;
578+
idealHeight = 42;
565579
}
566580

567581
void resized() override
568582
{
569-
auto const buttonWidth = getWidth() / 5;
570-
auto bounds = getLocalBounds();
583+
auto const bounds = getLocalBounds();
584+
auto const buttons = getButtons();
571585

572-
for (auto* button : SmallArray<TextButton*> { &cut, &copy, &paste, &duplicate, &remove }) {
573-
constexpr auto buttonHeight = 26;
574-
button->setBounds(bounds.removeFromLeft(buttonWidth).withHeight(buttonHeight));
586+
for (int i = 0; i < 5; ++i) {
587+
auto const left = bounds.getX() + bounds.getWidth() * i / 5;
588+
auto const right = bounds.getX() + bounds.getWidth() * (i + 1) / 5;
589+
590+
buttons[i]->setBounds(
591+
left, bounds.getY(),
592+
right - left, bounds.getHeight());
575593
}
576594
}
577595

578-
QuickActionButton cut = QuickActionButton(Icons::Cut);
579-
QuickActionButton copy = QuickActionButton(Icons::Copy);
580-
QuickActionButton paste = QuickActionButton(Icons::Paste);
581-
QuickActionButton duplicate = QuickActionButton(Icons::Duplicate);
582-
QuickActionButton remove = QuickActionButton(Icons::Trash);
583-
};
596+
private:
597+
StackArray<QuickActionButton*, 5> getButtons()
598+
{
599+
return { &cut, &copy, &paste, &duplicate, &remove };
600+
}
601+
602+
QuickActionButton cut { Icons::Cut, "Cut" };
603+
QuickActionButton copy { Icons::Copy, "Copy" };
604+
QuickActionButton paste { Icons::Paste, "Paste" };
605+
QuickActionButton duplicate { Icons::Duplicate, "Duplicate" };
606+
QuickActionButton remove { Icons::Trash, "Delete" };
607+
};;
584608

585609
// We have a custom function for this, instead of the default JUCE way, because the default JUCE way is broken on Linux
586610
// It will not find a target to apply the command to once the popupmenu grabs focus...

Source/Dialogs/MainMenu.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,7 @@ class MainMenu : public PopupMenu {
140140
auto const colour = findColour(PopupMenu::textColourId).withMultipliedAlpha(isActive ? 1.0f : 0.5f);
141141
if (isItemHighlighted() && isActive) {
142142
g.setColour(getThemeColours(*this).popupMenuActiveBackgroundColour);
143-
144-
g.fillRoundedRectangle(r.toFloat().reduced(0, 1), Corners::defaultCornerRadius);
143+
g.fillRoundedRectangle(r.toFloat(), Corners::defaultCornerRadius);
145144
}
146145

147146
g.setColour(colour);

Source/LookAndFeel.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ void PlugDataLook::getIdealPopupMenuItemSize(String const& text, bool const isSe
271271
if (standardMenuItemHeight > 0 && font.getHeight() > static_cast<float>(standardMenuItemHeight) / 1.3f)
272272
font.setHeight(static_cast<float>(standardMenuItemHeight) / 1.3f);
273273

274-
idealHeight = standardMenuItemHeight > 0 ? standardMenuItemHeight : roundToInt(font.getHeight() * 1.3f);
274+
idealHeight = standardMenuItemHeight > 0 ? standardMenuItemHeight : roundToInt(font.getHeight() * 1.4f);
275275
idealWidth = Fonts::getStringWidth(text, font) + idealHeight;
276276

277277
#if !JUCE_MAC
@@ -397,11 +397,10 @@ void PlugDataLook::drawPopupMenuItem(Graphics& g, Rectangle<int> const& area,
397397
auto width = std::max(Fonts::getStringWidthInt(text, font) + 4, 16);
398398
auto b = shortcutBounds.removeFromRight(width).toFloat().reduced(1.0f, 5.0f).translated(1.5f, 0.5f);
399399

400-
g.setColour(colours.popupMenuTextColour.withAlpha(isActive ? 0.9f : 0.35f));
400+
g.setColour(colours.popupMenuBackgroundColour.contrasting(0.08f));
401401
g.fillRoundedRectangle(b.toFloat(), 3.0f);
402402

403-
g.setColour(colours.popupMenuBackgroundColour);
404-
403+
g.setColour(colours.popupMenuTextColour.withAlpha(isActive ? 0.8f : 0.3f));
405404
g.setFont(Fonts::getSemiBoldFont().withHeight(11));
406405
g.drawText(text, b, Justification::centred);
407406
}
@@ -476,7 +475,7 @@ void PlugDataLook::drawComboBox(Graphics& g, int const width, int const height,
476475

477476
PopupMenu::Options PlugDataLook::getOptionsForComboBoxPopupMenu(ComboBox& box, Label& label)
478477
{
479-
auto options = PopupMenu::Options().withTargetComponent(&box).withItemThatMustBeVisible(box.getSelectedId()).withInitiallySelectedItem(box.getSelectedId()).withMinimumWidth(box.getWidth()).withMaximumNumColumns(1).withStandardItemHeight(22);
478+
auto options = PopupMenu::Options().withTargetComponent(&box).withItemThatMustBeVisible(box.getSelectedId()).withInitiallySelectedItem(box.getSelectedId()).withMinimumWidth(box.getWidth()).withMaximumNumColumns(1).withStandardItemHeight(24);
480479

481480
#if JUCE_IOS
482481
if (mainComponent)

Source/TabComponent.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,7 @@ void TabComponent::resized()
11581158
tabButton->setVisible(true);
11591159

11601160
int const tabWidth = tabWidths[t];
1161-
auto targetBounds = splitBounds.removeFromLeft(tabWidth);
1161+
auto targetBounds = splitBounds.removeFromLeft(tabWidth).translated(0, -1);
11621162
if (tabButton->isDragging) {
11631163
tabButton->setSize(tabWidth, 30);
11641164
if (splits[1]) {

Source/Toolbar.cpp

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,19 +1194,19 @@ class LimiterButton final : public TextButton {
11941194
auto const& colours = getThemeColours(*this);
11951195

11961196
auto const inactiveColour = colours.toolbarHoverColour;
1197-
auto const activeColour = colours.toolbarActiveColour.interpolatedWith(colours.toolbarBackgroundColour, 0.8f);
1197+
auto const activeColour = colours.toolbarActiveColour.interpolatedWith(colours.toolbarBackgroundColour, 0.86f);
11981198

11991199
constexpr float cornerRadius = Corners::defaultCornerRadius;
12001200

12011201
auto const textSegment = getLocalBounds().withWidth(getWidth());
12021202
auto const iconSegment = getLocalBounds().withLeft(getWidth());
12031203

1204-
auto textColour = getToggleState() ? activeColour : inactiveColour;
1204+
auto buttonColour = getToggleState() ? activeColour : inactiveColour;
12051205
if (isMouseOver() && !iconSegment.contains(getMouseXYRelative())) {
1206-
textColour = textColour.contrasting(0.2f);
1206+
buttonColour = buttonColour.contrasting(0.2f);
12071207
}
12081208

1209-
g.setColour(textColour);
1209+
g.setColour(buttonColour);
12101210
Path textPath;
12111211
textPath.addRoundedRectangle(0.0f, textSegment.getY() + 0.5f, textSegment.getWidth(), textSegment.getHeight() - 1.0f, cornerRadius, cornerRadius, false, true, false, true);
12121212
g.fillPath(textPath);
@@ -1221,7 +1221,8 @@ class LimiterButton final : public TextButton {
12211221
iconColour = iconColour.contrasting(0.2f);
12221222
}
12231223

1224-
g.setColour(colours.toolbarTextColour.withAlpha(0.8f));
1224+
auto textColour = getToggleState() ? colours.toolbarActiveColour : colours.toolbarTextColour.withAlpha(0.8f);
1225+
g.setColour(textColour);
12251226
g.setFont(Fonts::getSemiBoldFont().withHeight(13.5f));
12261227
g.drawText(getButtonText(), 0, 0, getWidth(), getHeight(), Justification::centred);
12271228
}
@@ -1532,12 +1533,16 @@ class PowerButton final : public Component
15321533
toggle.setTooltip("Enable/disable DSP");
15331534
toggle.setClickingTogglesState(true);
15341535
toggle.setToggleState(pd_getdspstate(), dontSendNotification);
1535-
toggle.onClick = [this] { toggle.getToggleState() ? pd->startDSP() : pd->releaseDSP(); };
1536+
toggle.onClick = [this] {
1537+
toggle.getToggleState() ? pd->startDSP() : pd->releaseDSP();
1538+
repaint();
1539+
};
15361540

15371541
chevron.setTooltip("DSP options");
15381542
chevron.setButtonText(Icons::ThinDown);
15391543
chevron.onClick = [this] {
15401544
showCallout();
1545+
repaint();
15411546
};
15421547

15431548
toggle.addMouseListener(this, false);
@@ -1591,31 +1596,28 @@ class PowerButton final : public Component
15911596
constexpr float cornerRadius = Corners::defaultCornerRadius;
15921597
auto const chevronWidth = 14.0f;
15931598

1599+
auto const buttonColour = toggle.getToggleState() ? colours.toolbarActiveColour.interpolatedWith(colours.toolbarBackgroundColour, 0.86f) : colours.toolbarBackgroundColour;
1600+
15941601
auto const togglePart = bounds.withWidth(bounds.getWidth() - chevronWidth);
15951602
auto const chevronPart = bounds.withLeft(bounds.getRight() - chevronWidth);
15961603

1597-
// Draw toggle
1598-
if(toggleHovered || chevronHovered) {
1599-
{
1600-
Path p;
1601-
p.addRoundedRectangle(togglePart.getX(), togglePart.getY(),
1602-
togglePart.getWidth(), togglePart.getHeight(),
1603-
cornerRadius, cornerRadius,
1604-
true, false, true, false);
1605-
g.setColour(colours.toolbarHoverColour.withAlpha(toggleHovered ? 1.0f : 0.5f));
1606-
g.fillPath(p);
1607-
}
1608-
1609-
1610-
{
1611-
Path p;
1612-
p.addRoundedRectangle(chevronPart.getX(), chevronPart.getY(),
1613-
chevronPart.getWidth(), chevronPart.getHeight(),
1614-
cornerRadius, cornerRadius,
1615-
false, true, false, true);
1616-
g.setColour(colours.toolbarHoverColour.withAlpha(chevronHovered ? 1.0f : 0.5f));
1617-
g.fillPath(p);
1618-
}
1604+
{
1605+
Path p;
1606+
p.addRoundedRectangle(togglePart.getX(), togglePart.getY(),
1607+
togglePart.getWidth(), togglePart.getHeight(),
1608+
cornerRadius, cornerRadius,
1609+
true, false, true, false);
1610+
g.setColour(buttonColour.contrasting(toggleHovered ? 0.05f : 0.0f));
1611+
g.fillPath(p);
1612+
}
1613+
{
1614+
Path p;
1615+
p.addRoundedRectangle(chevronPart.getX(), chevronPart.getY(),
1616+
chevronPart.getWidth(), chevronPart.getHeight(),
1617+
cornerRadius, cornerRadius,
1618+
false, true, false, true);
1619+
g.setColour(buttonColour.contrasting(chevronHovered ? 0.05f : 0.0f));
1620+
g.fillPath(p);
16191621
}
16201622
}
16211623

0 commit comments

Comments
 (0)