diff options
author | Daniel Bertalan <dani@danielbertalan.dev> | 2021-05-28 21:26:39 +0200 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-06-04 09:02:43 +0100 |
commit | acbd1d14d0ca8ea063a9acaec988913557acd22b (patch) | |
tree | c5b38b2d961a6e0dc96bce594159e8af9710ca4c /Userland | |
parent | 99033876ec6fc7484d7967d6cbd64f79669c21f7 (diff) | |
download | serenity-acbd1d14d0ca8ea063a9acaec988913557acd22b.zip |
LibVT+Terminal: Add color scheme support
This commit introduces color scheme support to Terminal. These are found
in `/res/terminal_colors` and the default color scheme can be set in
`~/.config/Terminal.ini`. Furthermore, a combo box is added for
setting the color scheme at runtime.
The previously used default color scheme has been added to
`/res/terminal-colors/Default.ini`.
To make the implementation more compatible with other color schemes,
`TerminalWidget` now supports overriding the default foreground and
background colors.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Applications/Terminal/TerminalSettingsWindow.gml | 13 | ||||
-rw-r--r-- | Userland/Applications/Terminal/main.cpp | 25 | ||||
-rw-r--r-- | Userland/Libraries/LibVT/TerminalWidget.cpp | 61 | ||||
-rw-r--r-- | Userland/Libraries/LibVT/TerminalWidget.h | 10 |
4 files changed, 104 insertions, 5 deletions
diff --git a/Userland/Applications/Terminal/TerminalSettingsWindow.gml b/Userland/Applications/Terminal/TerminalSettingsWindow.gml index 07b8400c56..6c906fd463 100644 --- a/Userland/Applications/Terminal/TerminalSettingsWindow.gml +++ b/Userland/Applications/Terminal/TerminalSettingsWindow.gml @@ -60,4 +60,17 @@ orientation: "Horizontal" } } + + @GUI::GroupBox { + title: "Color scheme" + shrink_to_fit: true + + layout: @GUI::VerticalBoxLayout { + margins: [6, 16, 6, 6] + } + + @GUI::ComboBox { + name: "color_scheme_combo" + } + } } diff --git a/Userland/Applications/Terminal/main.cpp b/Userland/Applications/Terminal/main.cpp index 846b0ffdd2..dd8fc9e325 100644 --- a/Userland/Applications/Terminal/main.cpp +++ b/Userland/Applications/Terminal/main.cpp @@ -4,10 +4,12 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <AK/QuickSort.h> #include <AK/URL.h> #include <Applications/Terminal/TerminalSettingsWindowGML.h> #include <LibCore/ArgsParser.h> #include <LibCore/ConfigFile.h> +#include <LibCore/DirIterator.h> #include <LibCore/File.h> #include <LibDesktop/Launcher.h> #include <LibGUI/Action.h> @@ -16,9 +18,11 @@ #include <LibGUI/BoxLayout.h> #include <LibGUI/Button.h> #include <LibGUI/CheckBox.h> +#include <LibGUI/ComboBox.h> #include <LibGUI/Event.h> #include <LibGUI/FontPicker.h> #include <LibGUI/Icon.h> +#include <LibGUI/ItemListModel.h> #include <LibGUI/Menu.h> #include <LibGUI/Menubar.h> #include <LibGUI/OpacitySlider.h> @@ -105,7 +109,7 @@ static RefPtr<GUI::Window> create_settings_window(VT::TerminalWidget& terminal) window->set_window_type(GUI::WindowType::ToolWindow); window->set_title("Terminal settings"); window->set_resizable(false); - window->resize(200, 210); + window->resize(200, 240); window->center_within(*terminal.window()); auto& settings = window->set_main_widget<GUI::Widget>(); @@ -149,6 +153,25 @@ static RefPtr<GUI::Window> create_settings_window(VT::TerminalWidget& terminal) terminal.set_max_history_size(value); }; + // The settings window takes a reference to this vector, so it needs to outlive this scope. + // As long as we ensure that only one settings window may be open at a time (which we do), + // this should cause no problems. + static Vector<String> color_scheme_names; + color_scheme_names.clear(); + Core::DirIterator iterator("/res/terminal-colors", Core::DirIterator::SkipParentAndBaseDir); + while (iterator.has_next()) { + auto path = iterator.next_path(); + path.replace(".ini", ""); + color_scheme_names.append(path); + } + quick_sort(color_scheme_names); + auto& color_scheme_combo = *settings.find_descendant_of_type_named<GUI::ComboBox>("color_scheme_combo"); + color_scheme_combo.set_only_allow_values_from_model(true); + color_scheme_combo.set_model(*GUI::ItemListModel<String>::create(color_scheme_names)); + color_scheme_combo.set_selected_index(color_scheme_names.find_first_index(terminal.color_scheme_name()).value()); + color_scheme_combo.on_change = [&](auto&, const GUI::ModelIndex& index) { + terminal.set_color_scheme(index.data().as_string()); + }; return window; } diff --git a/Userland/Libraries/LibVT/TerminalWidget.cpp b/Userland/Libraries/LibVT/TerminalWidget.cpp index 6998a8a96d..f010e8ed69 100644 --- a/Userland/Libraries/LibVT/TerminalWidget.cpp +++ b/Userland/Libraries/LibVT/TerminalWidget.cpp @@ -79,6 +79,9 @@ TerminalWidget::TerminalWidget(int ptm_fd, bool automatic_size_policy, RefPtr<Co , m_automatic_size_policy(automatic_size_policy) , m_config(move(config)) { + static_assert(sizeof(m_colors) == sizeof(xterm_colors)); + memcpy(m_colors, xterm_colors, sizeof(m_colors)); + set_override_cursor(Gfx::StandardCursor::IBeam); set_focus_policy(GUI::FocusPolicy::StrongFocus); set_accepts_emoji_input(true); @@ -147,6 +150,8 @@ TerminalWidget::TerminalWidget(int ptm_fd, bool automatic_size_policy, RefPtr<Co update_copy_action(); update_paste_action(); + + set_color_scheme(m_config->read_entry("Window", "ColorScheme", "Default")); } TerminalWidget::~TerminalWidget() @@ -1135,6 +1140,54 @@ void TerminalWidget::update_paste_action() m_paste_action->set_enabled(GUI::Clipboard::the().mime_type().starts_with("text/") && !GUI::Clipboard::the().data().is_empty()); } +void TerminalWidget::set_color_scheme(const StringView& name) +{ + if (name.contains('/')) { + dbgln("Shenanigans! Color scheme names can't contain slashes."); + return; + } + + m_color_scheme_name = name; + + constexpr StringView color_names[] = { + "Black", + "Red", + "Green", + "Yellow", + "Blue", + "Magenta", + "Cyan", + "White" + }; + + auto color_config = Core::ConfigFile::open(String::formatted("/res/terminal-colors/{}.ini", name)); + + auto default_background = Gfx::Color::from_string(color_config->read_entry("Primary", "Background")); + if (default_background.has_value()) + m_default_background_color = default_background.value(); + else + m_default_background_color = Gfx::Color::from_rgb(m_colors[(u8)VT::Color::ANSIColor::Black]); + + auto default_foreground = Gfx::Color::from_string(color_config->read_entry("Primary", "Foreground")); + if (default_foreground.has_value()) + m_default_foreground_color = default_foreground.value(); + else + m_default_foreground_color = Gfx::Color::from_rgb(m_colors[(u8)VT::Color::ANSIColor::White]); + + for (u8 color_idx = 0; color_idx < 8; ++color_idx) { + auto rgb = Gfx::Color::from_string(color_config->read_entry("Normal", color_names[color_idx])); + if (rgb.has_value()) + m_colors[color_idx] = rgb.value().value(); + } + + for (u8 color_idx = 0; color_idx < 8; ++color_idx) { + auto rgb = Gfx::Color::from_string(color_config->read_entry("Bright", color_names[color_idx])); + if (rgb.has_value()) + m_colors[color_idx + 8] = rgb.value().value(); + } + update(); +} + Gfx::IntSize TerminalWidget::widget_size_for_font(const Gfx::Font& font) const { return { @@ -1149,15 +1202,15 @@ Gfx::Color TerminalWidget::terminal_color_to_rgb(VT::Color color) case VT::Color::Kind::RGB: return Gfx::Color::from_rgb(color.as_rgb()); case VT::Color::Kind::Indexed: - return Gfx::Color::from_rgb(xterm_colors[color.as_indexed()]); + return Gfx::Color::from_rgb(m_colors[color.as_indexed()]); case VT::Color::Kind::Named: { auto ansi = color.as_named(); if ((u16)ansi < 256) - return Gfx::Color::from_rgb(xterm_colors[(u16)ansi]); + return Gfx::Color::from_rgb(m_colors[(u16)ansi]); else if (ansi == VT::Color::ANSIColor::DefaultForeground) - return Gfx::Color::from_rgb(xterm_colors[7]); + return m_default_foreground_color; else if (ansi == VT::Color::ANSIColor::DefaultBackground) - return Gfx::Color::from_rgb(xterm_colors[0]); + return m_default_background_color; else VERIFY_NOT_REACHED(); } diff --git a/Userland/Libraries/LibVT/TerminalWidget.h b/Userland/Libraries/LibVT/TerminalWidget.h index 39d8a7f2e9..5d4307e651 100644 --- a/Userland/Libraries/LibVT/TerminalWidget.h +++ b/Userland/Libraries/LibVT/TerminalWidget.h @@ -81,6 +81,8 @@ public: void paste(); void clear_including_history(); + const StringView color_scheme_name() const { return m_color_scheme_name; } + Function<void(const StringView&)> on_title_change; Function<void(const Gfx::IntSize&)> on_terminal_size_change; Function<void()> on_command_exit; @@ -91,6 +93,8 @@ public: void set_font_and_resize_to_fit(const Gfx::Font&); + void set_color_scheme(const StringView&); + private: // ^GUI::Widget virtual void event(Core::Event&) override; @@ -157,6 +161,12 @@ private: // Snapshot of m_hovered_href when opening a context menu for a hyperlink. String m_context_menu_href; + unsigned m_colors[256]; + Gfx::Color m_default_foreground_color; + Gfx::Color m_default_background_color; + + String m_color_scheme_name; + BellMode m_bell_mode { BellMode::Visible }; bool m_alt_key_held { false }; bool m_rectangle_selection { false }; |