ml::docs | Your First App Manifests Events Messaging Plugins Scenes Resources
See all tutorials →
Beginner 5 sections ~9 min C++17/20

Colour Pickers

Palettes, gradients and the tabbed chooser that combines them — plus the distinction between previewing a colour and committing to one.

Introduction

Four Controls

Four controls cover colour selection, from picking one of yours to picking any colour at all.

ControlChooses from
ColorButtonNothing — it shows a colour and reports a click
ColorPickerA palette you supply
GradientColorPickerThe full spectrum, by dragging
ColorChooserBoth, in one tabbed control
Start with ColorChooser unless you know you want to restrict the choice. Offering a palette and a spectrum in one control is what users expect, and it is one component rather than three.
1Fixed

ColorPicker

ColorPicker presents a fixed set of swatches — a theme palette, a set of highlight colours, whatever you define.

ml::ColorPicker picker;
picker.setPalette({ sf::Color(166,129,255), sf::Color(240,200,40),
                    sf::Color(103,199,138), sf::Color(220,60,60) });
picker.setMaxColors(12);
MethodEffect
setPalette(colors)Replace the whole set.
addColor(c)Append one swatch.
removeColor(index)Remove by position.
setMaxColors(n)Cap how many the user may add.
onColorRemoved(cb)Fires when a swatch is removed.
onSwatchRightClick(cb)Position plus index — hook a context menu here.
onSwatchRightClick gives you the swatch index and screen position, which is exactly what ContextMenu::showAt wants — that pairing is how you offer "remove" or "edit" on a palette entry.
2Continuous

GradientColorPicker

GradientColorPicker is the continuous one: drag across a spectrum.

ml::GradientColorPicker grad;
grad.setSize({260.f, 180.f});
grad.setColor(current);
grad.onColorChanged([&](const sf::Color& c){ preview.setFillColor(c); });  // live
grad.onCommit([&]{ applyColor(); });                                       // released
CallbackFires
onColorChanged(cb)Continuously while dragging.
onCommit(cb)Once, when the drag ends.
Use both, for different work. onColorChanged should only update a preview — it fires many times per second. Anything expensive, or anything that writes to disk or the network, belongs in onCommit.
3Combined

ColorChooser

ColorChooser combines a palette and a gradient behind tabs.

ml::ColorChooser chooser;
chooser.setColor(sf::Color(166,129,255));
chooser.setMaxSwatches(16);
chooser.onColorSelected([&](const sf::Color& c){ setBrush(c); });
MethodEffect
setColor(c)Set the current selection.
onColorSelected(cb)The user has settled on a colour.
onColorChanged(cb)The colour is moving — preview only.
setMaxSwatches(n)Cap the palette side.
setLayout(layout)Arrangement of the tabs.
showTab(index)Open on a specific tab.
The same split applies: onColorSelected is the decision, onColorChanged is the journey. Committing on every change makes undo history useless — one deliberate colour choice becomes fifty entries.
4Trigger

ColorButton

ColorButton displays a colour and reports clicks. It is the trigger you attach a chooser to.

ml::ColorButton swatch;
swatch.setSize({28.f, 28.f});
swatch.setColorProvider([&]{ return brush.color(); });   // always current
swatch.onClick([&]{ chooser.setVisible(true); });
setColorProvider pulls the colour each frame rather than storing it, so the button cannot fall out of sync with the value it represents. Prefer it to setColor whenever the underlying colour can change from elsewhere.