From d6326d6c2ec6a2849f3f0ad0e16c1df3ac0fc326 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 12 Feb 2019 14:35:33 +0100 Subject: [PATCH] LibGUI: Add a GFontDatabase class that lets you enumerate fonts and more. "More" in this case being also giving you the ability to load a font by name. Use this as backend for Terminal's font menu. :^) --- Applications/Terminal/main.cpp | 15 +++++----- LibGUI/GFontDatabase.cpp | 50 ++++++++++++++++++++++++++++++++++ LibGUI/GFontDatabase.h | 21 ++++++++++++++ LibGUI/Makefile | 1 + 4 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 LibGUI/GFontDatabase.cpp create mode 100644 LibGUI/GFontDatabase.h diff --git a/Applications/Terminal/main.cpp b/Applications/Terminal/main.cpp index eb20db6fe48..58563dfab2d 100644 --- a/Applications/Terminal/main.cpp +++ b/Applications/Terminal/main.cpp @@ -15,6 +15,7 @@ #include #include #include +#include static void make_shell(int ptm_fd) { @@ -104,14 +105,12 @@ int main(int argc, char** argv) menubar->add_menu(move(app_menu)); auto font_menu = make("Font"); - auto handle_font_selection = [&terminal] (const GAction& action) { - terminal.set_font(Font::load_from_file(action.custom_data())); - terminal.force_repaint(); - }; - font_menu->add_action(make("Liza Thin", "/res/fonts/LizaThin8x10.font", move(handle_font_selection))); - font_menu->add_action(make("Liza Regular", "/res/fonts/LizaRegular8x10.font", move(handle_font_selection))); - font_menu->add_action(make("Liza Bold", "/res/fonts/LizaBold8x10.font", move(handle_font_selection))); - + GFontDatabase::the().for_each_font([&] (const String& font_name) { + font_menu->add_action(make(font_name, [&terminal] (const GAction& action) { + terminal.set_font(GFontDatabase::the().get_by_name(action.text())); + terminal.force_repaint(); + })); + }); menubar->add_menu(move(font_menu)); auto help_menu = make("Help"); diff --git a/LibGUI/GFontDatabase.cpp b/LibGUI/GFontDatabase.cpp new file mode 100644 index 00000000000..a07d21ddd15 --- /dev/null +++ b/LibGUI/GFontDatabase.cpp @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include + +static GFontDatabase* s_the; + +GFontDatabase& GFontDatabase::the() +{ + if (!s_the) + s_the = new GFontDatabase; + return *s_the; +} + +GFontDatabase::GFontDatabase() +{ + DIR* dirp = opendir("/res/fonts"); + if (!dirp) { + perror("opendir"); + exit(1); + } + while (auto* de = readdir(dirp)) { + if (de->d_name[0] == '.') + continue; + auto path = String::format("/res/fonts/%s", de->d_name); + if (auto font = Font::load_from_file(path)) + m_name_to_path.set(font->name(), path); + } + closedir(dirp); +} + +GFontDatabase::~GFontDatabase() +{ +} + +void GFontDatabase::for_each_font(Function callback) +{ + for (auto& it : m_name_to_path) { + callback(it.key); + } +} + +RetainPtr GFontDatabase::get_by_name(const String& name) +{ + auto it = m_name_to_path.find(name); + if (it == m_name_to_path.end()) + return nullptr; + return Font::load_from_file((*it).value); +} diff --git a/LibGUI/GFontDatabase.h b/LibGUI/GFontDatabase.h new file mode 100644 index 00000000000..7ed0c4f7e18 --- /dev/null +++ b/LibGUI/GFontDatabase.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include +#include + +class Font; + +class GFontDatabase { +public: + static GFontDatabase& the(); + + RetainPtr get_by_name(const String&); + void for_each_font(Function); + +private: + GFontDatabase(); + ~GFontDatabase(); + + HashMap m_name_to_path; +}; diff --git a/LibGUI/Makefile b/LibGUI/Makefile index f148566f5dd..e1dcfaa3852 100644 --- a/LibGUI/Makefile +++ b/LibGUI/Makefile @@ -26,6 +26,7 @@ LIBGUI_OBJS = \ GMenuItem.o \ GApplication.o \ GAction.o \ + GFontDatabase.o \ GWindow.o OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS)