241FontList::FontList(Glib::ustring preferences_path) :
242 _prefs(
std::move(preferences_path)),
246 _font_list(
get_widget<
Gtk::TreeView>(_builder,
"font-list")),
247 _font_grid(
get_widget<
Gtk::IconView>(_builder,
"font-grid")),
248 _font_size(
get_widget<
Gtk::ComboBoxText>(_builder,
"font-size")),
249 _font_size_scale(
get_widget<
Gtk::Scale>(_builder,
"font-size-scale")),
252 _progress_box(
get_widget<
Gtk::Box>(_builder,
"progress-box")),
256 auto font_renderer =
static_cast<CellFontRenderer*
>(
_cell_renderer.get());
261 ico->set_fixed_size(16, 16);
264 auto grid_renderer =
static_cast<CellFontRenderer*
>(
_grid_renderer.get());
265 grid_renderer->_show_font_name =
false;
283 set_margin_bottom(0);
285 auto options = &get_widget<Gtk::ToggleButton>(
_builder,
"btn-options");
286 auto options_grid = &get_widget<Gtk::Grid>(
_builder,
"options-grid");
287 options->signal_toggled().connect([=](){
288 options_grid->set_visible(options->get_active());
291 std::pair<const char*, Inkscape::FontOrder> sorting[3] = {
296 auto sort_menu = Gtk::make_managed<PopoverMenu>(Gtk::PositionType::BOTTOM);
297 for (
auto&& el : sorting) {
298 auto item = Gtk::make_managed<PopoverMenuItem>();
299 auto hbox = Gtk::make_managed<Gtk::Box>();
301 hbox->append(*Gtk::make_managed<Gtk::Label>(_(el.first)));
302 hbox->set_spacing(4);
303 item->set_child(*hbox);
304 item->signal_activate().connect([=,
this] {
sort_fonts(el.second); });
305 sort_menu->append(*
item);
307 get_widget<Gtk::MenuButton>(
_builder,
"btn-sort").set_popover(*sort_menu);
308 get_widget<Gtk::Button>(
_builder,
"id-reset-filter").signal_clicked().connect([
this](){
309 bool modified =
false;
314 if (!fc->get_selected_collections().empty()) {
315 fc->clear_selected_collections();
324 auto search = &get_widget<Gtk::SearchEntry2>(
_builder,
"font-search");
325 search->signal_changed().connect([
this](){
filter(); });
327 auto set_row_height = [font_renderer,
this](
int font_size_percent) {
328 font_renderer->_font_size = font_size_percent;
330 int hh = (font_renderer->_show_font_name ? 10 : 0) + 18 * font_renderer->_font_size / 100;
331 font_renderer->set_fixed_size(-1, hh);
336 auto set_grid_size = [=](
int font_size_percent) {
337 grid_renderer->_font_size = font_size_percent;
343 font_renderer->_font_size = prefs->getIntLimited(
_prefs +
"/preview-size", 200, 100, 800);
344 auto size = &get_widget<Gtk::Scale>(
_builder,
"preview-font-size");
345 size->set_format_value_func([](
double val){
346 return Glib::ustring::format(std::fixed, std::setprecision(0), val) +
"%";
348 size->set_value(font_renderer->_font_size);
349 size->signal_value_changed().connect([=,
this](){
350 auto font_size =
size->get_value();
351 set_row_height(font_size);
352 set_grid_size(font_size);
353 prefs->setInt(
_prefs +
"/preview-size", font_size);
358 auto show_names = &get_widget<Gtk::CheckButton>(
_builder,
"show-font-name");
359 auto set_show_names = [=,
this](
bool show) {
360 font_renderer->_show_font_name = show;
361 prefs->setBool(
_prefs +
"/show-font-names", show);
362 set_row_height(font_renderer->_font_size);
363 _font_list.set_grid_lines(show ? Gtk::TreeView::GridLines::HORIZONTAL : Gtk::TreeView::GridLines::NONE);
367 auto show = prefs->getBool(
_prefs +
"/show-font-names",
true);
368 set_show_names(show);
369 show_names->set_active(show);
370 show_names->signal_toggled().connect([=](){
371 bool show = show_names->get_active();
372 set_show_names(show);
376 auto sample = &get_widget<Gtk::Entry>(
_builder,
"sample-text");
377 auto sample_text = prefs->getString(
_prefs +
"/sample-text");
378 sample->set_text(sample_text);
379 font_renderer->_sample_text = sample_text;
380 sample->signal_changed().connect([=,
this](){
381 auto text = sample->get_text();
382 font_renderer->_sample_text = text;
383 prefs->setString(
_prefs +
"/sample-text", text);
387 auto grid_sample = &get_widget<Gtk::Entry>(
_builder,
"grid-sample");
388 auto sample_grid_text = prefs->getString(
_prefs +
"/grid-text",
"Aa");
389 grid_sample->set_text(sample_grid_text);
390 grid_renderer->_sample_text = sample_grid_text;
391 grid_sample->signal_changed().connect([=,
this](){
392 auto text = grid_sample->get_text();
393 grid_renderer->_sample_text = text.empty() ?
"?" : text;
394 prefs->setString(
_prefs +
"/grid-text", text);
399 auto samples_submenu = get_object<Gio::Menu>(
_builder,
"samples-submenu");
400 auto samples_stringlist = get_object<Gtk::StringList>(
_builder,
"samples-stringlist");
402 auto truncate = [] (Glib::ustring
const &text) {
403 constexpr int N = 30;
404 if (text.length() <=
N) {
408 auto substr = text.substr(0,
N);
409 auto pos = substr.rfind(
' ');
411 if (pos != Glib::ustring::npos && pos >
N -
N / 4) {
413 substr = substr.substr(0, pos);
419 for (
int i = 0, n_items = samples_stringlist->get_n_items(); i < n_items; i++) {
420 auto text = samples_stringlist->get_string(i);
421 auto menu_item = Gio::MenuItem::create(truncate(text),
"");
422 menu_item->set_action_and_target(
"win.set-sample", Glib::Variant<Glib::ustring>::create(text));
423 samples_submenu->append_item(menu_item);
427 auto action_group = Gio::SimpleActionGroup::create();
428 action_group->add_action_with_parameter(
"set-sample", Glib::Variant<Glib::ustring>::variant_type(), [=] (Glib::VariantBase
const ¶m) {
429 auto param_str = Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring>>(param).get();
430 sample->set_text(param_str);
432 insert_action_group(
"win", action_group);
434 _text_column.set_sizing(Gtk::TreeViewColumn::Sizing::FIXED);
441 Gtk::TreeModel::ConstRow row = *it;
448 set_row_height(font_renderer->_font_size);
455 grid_renderer->set_fixed_height_from_font(-1);
456 set_grid_size(grid_renderer->_font_size);
458 _font_grid.set_cell_data_func(*grid_renderer, [=](
const Gtk::TreeModel::const_iterator& it) {
459 Gtk::TreeModel::ConstRow row = *it;
463 _font_grid.signal_query_tooltip().connect([
this](
int x,
int y,
bool kbd,
const Glib::RefPtr<Gtk::Tooltip>& tt){
464 Gtk::TreeModel::iterator iter;
466 if (
_font_grid.get_tooltip_context_iter(x, y, kbd, iter)) {
471 return !
name.empty();
475 auto font_selected = [
this](
const FontInfo& font) {
479 auto vars = font.variations;
480 if (vars.empty() && font.variable_font) {
489 if (sel.size() == 1) {
490 auto it = _font_list_store->get_iter(sel.front());
491 const Inkscape::FontInfo& font = (*it)[g_column_model.font];
496 auto show_grid = &get_widget<Gtk::ToggleButton>(
_builder,
"view-grid");
497 auto show_list = &get_widget<Gtk::ToggleButton>(
_builder,
"view-list");
498 auto set_list_view_mode = [prefs,
this](
bool show_list) {
499 auto& list = get_widget<Gtk::ScrolledWindow>(
_builder,
"list");
500 auto& grid = get_widget<Gtk::ScrolledWindow>(
_builder,
"grid");
503 grid.set_visible(
false);
508 list.set_visible(
false);
513 get_widget<Gtk::Entry>(
_builder,
"grid-sample").set_visible(!show_list);
514 prefs->setBool(
_prefs +
"/list-view-mode", show_list);
516 auto list_mode = prefs->getBool(
_prefs +
"/list-view-mode",
true);
517 if (list_mode) show_list->set_active();
else show_grid->set_active();
518 set_list_view_mode(list_mode);
519 show_list->signal_toggled().connect([=] { set_list_view_mode(
true); });
520 show_grid->signal_toggled().connect([=] { set_list_view_mode(
false); });
527 auto prepare_tags = [
this](){
530 auto kind = f.family_kind >> 8;
534 else if (kind >= 1 && kind <= 5) {
537 else if (kind == 8) {
540 else if (kind == 12) {
547 if (f.variable_font) {
567 auto& progress = get_widget<Gtk::ProgressBar>(
_builder,
"init-progress");
568 progress.set_fraction(std::get<double>(*p));
569 progress.set_text(std::get<Glib::ustring>(*p));
570 auto&& family = std::get<std::vector<FontInfo>>(*p);
571 _fonts.insert(
_fonts.end(), family.begin(), family.end());
604 auto size = ::atof(text.c_str());
612 _font_size.get_entry()->set_max_width_chars(6);
616 _font_list.get_selection()->signal_changed().connect([=,
this](){
617 if (
auto iter =
_font_list.get_selection()->get_selected()) {
618 const Inkscape::FontInfo& font = (*iter)[g_column_model.font];
624 _font_list.signal_row_activated().connect([
this](
const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn*){
626 auto scoped = _update.block();
627 _signal_apply.emit();
635 auto& filter_popover = get_widget<Gtk::Popover>(
_builder,
"filter-popover");
636 filter_popover.signal_show().connect([
this](){