Pick the text stage's font with a font chooser
A new Font param type (ParamSpec::makeFont) is a font family as the machine names it. The interface shows it as a family-only FontDialogButton; the command line and the project file treat it as a plain string, as they did the Text param it replaces, so existing projects and --font-family keep working. A family the machine lacks is kept as written. Bumps the version to 0.8.1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -182,6 +182,7 @@ Options parseOptions(int argc, char** argv) {
|
||||
}
|
||||
case ParamSpec::Type::Path:
|
||||
case ParamSpec::Type::Text:
|
||||
case ParamSpec::Type::Font:
|
||||
options.params[spec->key] = requireValue(argc, argv, i, arg);
|
||||
break;
|
||||
case ParamSpec::Type::Color: {
|
||||
|
||||
@@ -100,6 +100,17 @@ ParamSpec ParamSpec::makeColor(std::string key, std::string label, std::string d
|
||||
return spec;
|
||||
}
|
||||
|
||||
ParamSpec ParamSpec::makeFont(std::string key, std::string label, std::string defaultFamily,
|
||||
std::string help) {
|
||||
ParamSpec spec;
|
||||
spec.type = Type::Font;
|
||||
spec.key = std::move(key);
|
||||
spec.label = std::move(label);
|
||||
spec.help = std::move(help);
|
||||
spec.defaultChoice = std::move(defaultFamily);
|
||||
return spec;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const ParamValue* find(const ParamValues& values, const std::string& key) {
|
||||
@@ -121,6 +132,7 @@ ParamValue paramDefault(const ParamSpec& spec) {
|
||||
case ParamSpec::Type::Path:
|
||||
case ParamSpec::Type::Text:
|
||||
case ParamSpec::Type::Color:
|
||||
case ParamSpec::Type::Font:
|
||||
break;
|
||||
}
|
||||
return spec.defaultChoice;
|
||||
|
||||
+6
-1
@@ -11,7 +11,7 @@ namespace effector {
|
||||
// Declarative description of one effect knob. The GUI turns these into widgets
|
||||
// and the CLI turns them into flags, so neither knows about any effect.
|
||||
struct ParamSpec {
|
||||
enum class Type { Int, Double, Bool, Choice, Path, Text, Color };
|
||||
enum class Type { Int, Double, Bool, Choice, Path, Text, Color, Font };
|
||||
|
||||
Type type = Type::Int;
|
||||
std::string key;
|
||||
@@ -56,6 +56,11 @@ struct ParamSpec {
|
||||
// spelling as a flag value.
|
||||
static ParamSpec makeColor(std::string key, std::string label, std::string defaultColor,
|
||||
std::string help = {});
|
||||
// A font family as it is named on this machine ("Sans", "DejaVu Serif"):
|
||||
// a font chooser in the interface, a flag taking any string on the
|
||||
// command line. A family the machine lacks is kept as written.
|
||||
static ParamSpec makeFont(std::string key, std::string label, std::string defaultFamily,
|
||||
std::string help = {});
|
||||
};
|
||||
|
||||
using ParamValue = std::variant<long, double, bool, std::string>;
|
||||
|
||||
@@ -366,6 +366,7 @@ void writeParams(std::ostream& out, const std::vector<ParamSpec>& specs, const P
|
||||
break;
|
||||
case ParamSpec::Type::Choice:
|
||||
case ParamSpec::Type::Text:
|
||||
case ParamSpec::Type::Font:
|
||||
out << quote(paramText(values, spec.key, spec.defaultChoice));
|
||||
break;
|
||||
case ParamSpec::Type::Color: {
|
||||
@@ -412,6 +413,7 @@ void readParams(const std::vector<ParamSpec>& specs, const Json& params,
|
||||
}
|
||||
break;
|
||||
case ParamSpec::Type::Text:
|
||||
case ParamSpec::Type::Font:
|
||||
if (value->kind == Json::Kind::String) values[spec.key] = value->text;
|
||||
break;
|
||||
case ParamSpec::Type::Color: {
|
||||
|
||||
@@ -16,7 +16,7 @@ const std::vector<ParamSpec>& TextEffect::params() const {
|
||||
static const std::vector<ParamSpec> specs = {
|
||||
ParamSpec::makeText("text", "Text", "Effector",
|
||||
"What to write; a line break starts a new line."),
|
||||
ParamSpec::makeText("font_family", "Font", "Sans",
|
||||
ParamSpec::makeFont("font_family", "Font", "Sans",
|
||||
"Font family, as it is named on this machine: Sans, Serif, Monospace, "
|
||||
"\"DejaVu Serif\", ...")
|
||||
.styled(),
|
||||
|
||||
@@ -995,6 +995,21 @@ void EffectorWindow::buildParamWidgets() {
|
||||
widget = std::move(button);
|
||||
break;
|
||||
}
|
||||
case ParamSpec::Type::Font: {
|
||||
// Only the family is chosen here: weight, slant and size are
|
||||
// params of their own.
|
||||
auto button = std::make_unique<Gtk::FontDialogButton>(Gtk::FontDialog::create());
|
||||
button->set_halign(Gtk::Align::START);
|
||||
button->set_level(Gtk::FontLevel::FAMILY);
|
||||
button->set_use_font(true);
|
||||
Pango::FontDescription font;
|
||||
font.set_family(paramText(values, spec.key, spec.defaultChoice));
|
||||
button->set_font_desc(font);
|
||||
button->property_font_desc().signal_changed().connect(
|
||||
sigc::mem_fun(*this, &EffectorWindow::onParamChanged));
|
||||
widget = std::move(button);
|
||||
break;
|
||||
}
|
||||
case ParamSpec::Type::Choice: {
|
||||
std::vector<Glib::ustring> choices(spec.choices.begin(), spec.choices.end());
|
||||
auto dropdown = std::make_unique<Gtk::DropDown>();
|
||||
@@ -1051,6 +1066,14 @@ ParamValues EffectorWindow::paramValues() const {
|
||||
values[entry.spec.key] = formatColor(rgb);
|
||||
break;
|
||||
}
|
||||
case ParamSpec::Type::Font: {
|
||||
// A family the machine lacks keeps its name, so a project
|
||||
// from elsewhere still says which font it wanted.
|
||||
const auto family =
|
||||
static_cast<Gtk::FontDialogButton*>(entry.widget)->get_font_desc().get_family();
|
||||
if (!family.empty()) values[entry.spec.key] = std::string(family);
|
||||
break;
|
||||
}
|
||||
case ParamSpec::Type::Choice: {
|
||||
const auto index = static_cast<Gtk::DropDown*>(entry.widget)->get_selected();
|
||||
if (index < entry.spec.choices.size()) values[entry.spec.key] = entry.spec.choices[index];
|
||||
|
||||
Reference in New Issue
Block a user