Code cleanups.
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
Release / Build Linux amd64 (push) Has been cancelled
Release / Build Linux arm64 (push) Has been cancelled
Release / Build macOS arm64 (.app) (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
Release / Build Linux amd64 (push) Has been cancelled
Release / Build Linux arm64 (push) Has been cancelled
Release / Build macOS arm64 (.app) (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
- Implement font management improvements - Add commands for font selection and size - Handle pending font loading consistently - Update related documentation. - Version bump to 1.3.1.
This commit is contained in:
@@ -4,7 +4,7 @@ project(kte)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(KTE_VERSION "1.3.0")
|
||||
set(KTE_VERSION "1.3.1")
|
||||
|
||||
# Default to terminal-only build to avoid SDL/OpenGL dependency by default.
|
||||
# Enable with -DBUILD_GUI=ON when SDL2/OpenGL/Freetype are available.
|
||||
|
||||
122
Command.cc
122
Command.cc
@@ -4,6 +4,7 @@
|
||||
#include <regex>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <cmath>
|
||||
#include <cctype>
|
||||
|
||||
#include "Command.h"
|
||||
@@ -18,6 +19,8 @@
|
||||
#include "syntax/CppHighlighter.h"
|
||||
#ifdef KTE_BUILD_GUI
|
||||
#include "GUITheme.h"
|
||||
#include "fonts/FontRegistry.h"
|
||||
#include "imgui.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -984,6 +987,117 @@ cmd_theme_set_by_name(CommandContext &ctx)
|
||||
#endif
|
||||
|
||||
|
||||
// Font set by name (GUI)
|
||||
#ifdef KTE_BUILD_GUI
|
||||
static bool
|
||||
cmd_font_set_by_name(const CommandContext &ctx)
|
||||
{
|
||||
using namespace kte::Fonts;
|
||||
std::string name = ctx.arg;
|
||||
// trim
|
||||
auto ltrim = [](std::string &s) {
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}));
|
||||
};
|
||||
auto rtrim = [](std::string &s) {
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}).base(), s.end());
|
||||
};
|
||||
ltrim(name);
|
||||
rtrim(name);
|
||||
std::transform(name.begin(), name.end(), name.begin(), [](unsigned char c) {
|
||||
return (char) std::tolower(c);
|
||||
});
|
||||
if (name.empty()) {
|
||||
ctx.editor.SetStatus("font: missing name");
|
||||
return true;
|
||||
}
|
||||
|
||||
auto ® = FontRegistry::Instance();
|
||||
if (!reg.HasFont(name)) {
|
||||
ctx.editor.SetStatus("font: unknown name");
|
||||
return true;
|
||||
}
|
||||
|
||||
float size = reg.CurrentFontSize();
|
||||
if (size <= 0.0f) {
|
||||
// Fallback to current ImGui font size if available
|
||||
size = ImGui::GetFontSize();
|
||||
if (size <= 0.0f)
|
||||
size = 16.0f;
|
||||
}
|
||||
reg.RequestLoadFont(name, size);
|
||||
ctx.editor.SetStatus(std::string("Font: ") + name + " (" + std::to_string((int) std::round(size)) + ")");
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static bool
|
||||
cmd_font_set_by_name(CommandContext &ctx)
|
||||
{
|
||||
(void) ctx;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Font size set (GUI)
|
||||
#ifdef KTE_BUILD_GUI
|
||||
static bool
|
||||
cmd_font_set_size(const CommandContext &ctx)
|
||||
{
|
||||
using namespace kte::Fonts;
|
||||
std::string a = ctx.arg;
|
||||
auto ltrim = [](std::string &s) {
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}));
|
||||
};
|
||||
auto rtrim = [](std::string &s) {
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}).base(), s.end());
|
||||
};
|
||||
ltrim(a);
|
||||
rtrim(a);
|
||||
if (a.empty()) {
|
||||
ctx.editor.SetStatus("font-size: missing value");
|
||||
return true;
|
||||
}
|
||||
char *endp = nullptr;
|
||||
float size = strtof(a.c_str(), &endp);
|
||||
if (endp == a.c_str() || !std::isfinite(size)) {
|
||||
ctx.editor.SetStatus("font-size: expected number");
|
||||
return true;
|
||||
}
|
||||
// Clamp to a reasonable range
|
||||
if (size < 6.0f)
|
||||
size = 6.0f;
|
||||
if (size > 96.0f)
|
||||
size = 96.0f;
|
||||
|
||||
auto ® = FontRegistry::Instance();
|
||||
std::string name = reg.CurrentFontName();
|
||||
if (name.empty())
|
||||
name = "default";
|
||||
if (!reg.HasFont(name))
|
||||
name = "default";
|
||||
|
||||
reg.RequestLoadFont(name, size);
|
||||
ctx.editor.SetStatus(std::string("Font size: ") + std::to_string((int) std::round(size)));
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static bool
|
||||
cmd_font_set_size(CommandContext &ctx)
|
||||
{
|
||||
(void) ctx;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Background set command (GUI)
|
||||
#ifdef KTE_BUILD_GUI
|
||||
static bool
|
||||
@@ -3781,6 +3895,14 @@ InstallDefaultCommands()
|
||||
CommandRegistry::Register({
|
||||
CommandId::ThemeSetByName, "theme", "Set GUI theme by name", cmd_theme_set_by_name, true
|
||||
});
|
||||
// Font by name (public)
|
||||
CommandRegistry::Register({
|
||||
CommandId::FontSetByName, "font", "Set GUI font by name", cmd_font_set_by_name, true
|
||||
});
|
||||
// Font size (public)
|
||||
CommandRegistry::Register({
|
||||
CommandId::FontSetSize, "font-size", "Set GUI font size (pixels)", cmd_font_set_size, true
|
||||
});
|
||||
// Background light/dark (public)
|
||||
CommandRegistry::Register({
|
||||
CommandId::BackgroundSet, "background", "Set GUI background light|dark", cmd_background_set, true
|
||||
|
||||
@@ -97,6 +97,8 @@ enum class CommandId {
|
||||
ThemeSetByName,
|
||||
// Font by name (GUI)
|
||||
FontSetByName,
|
||||
// Font size (GUI)
|
||||
FontSetSize,
|
||||
// Background mode (GUI)
|
||||
BackgroundSet,
|
||||
// Syntax highlighting
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "GUIConfig.h"
|
||||
#include "GUITheme.h"
|
||||
#include "fonts/Font.h" // embedded default font (DefaultFont)
|
||||
#include "fonts/FontRegistry.h"
|
||||
#include "syntax/HighlighterRegistry.h"
|
||||
#include "syntax/NullHighlighter.h"
|
||||
|
||||
@@ -196,8 +197,19 @@ GUIFrontend::Init(Editor &ed)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize GUI font from embedded default (use configured size or compiled default)
|
||||
LoadGuiFont_(nullptr, (float) cfg.font_size);
|
||||
// Install embedded fonts into registry and load configured font
|
||||
kte::Fonts::InstallDefaultFonts();
|
||||
// Initialize font atlas using configured font name and size; fallback to embedded default helper
|
||||
if (!kte::Fonts::FontRegistry::Instance().LoadFont(cfg.font, (float) cfg.font_size)) {
|
||||
LoadGuiFont_(nullptr, (float) cfg.font_size);
|
||||
// Record defaults in registry so subsequent size changes have a base
|
||||
kte::Fonts::FontRegistry::Instance().RequestLoadFont("default", (float) cfg.font_size);
|
||||
std::string n;
|
||||
float s = 0.0f;
|
||||
if (kte::Fonts::FontRegistry::Instance().ConsumePendingFontRequest(n, s)) {
|
||||
kte::Fonts::FontRegistry::Instance().LoadFont(n, s);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -226,6 +238,20 @@ GUIFrontend::Step(Editor &ed, bool &running)
|
||||
input_.ProcessSDLEvent(e);
|
||||
}
|
||||
|
||||
// Apply pending font change before starting a new frame
|
||||
{
|
||||
std::string fname;
|
||||
float fsize = 0.0f;
|
||||
if (kte::Fonts::FontRegistry::Instance().ConsumePendingFontRequest(fname, fsize)) {
|
||||
if (!fname.empty() && fsize > 0.0f) {
|
||||
kte::Fonts::FontRegistry::Instance().LoadFont(fname, fsize);
|
||||
// Recreate backend font texture
|
||||
ImGui_ImplOpenGL3_DestroyFontsTexture();
|
||||
ImGui_ImplOpenGL3_CreateFontsTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start a new ImGui frame BEFORE processing commands so dimensions are correct
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplSDL2_NewFrame(window_);
|
||||
|
||||
@@ -573,8 +573,6 @@ GUIInputHandler::ProcessSDLEvent(const SDL_Event &e)
|
||||
if (produced && mi.hasCommand) {
|
||||
// Attach universal-argument count if present, then clear the state
|
||||
if (uarg_active_ &&mi
|
||||
|
||||
|
||||
|
||||
.
|
||||
id != CommandId::UArgStatus
|
||||
@@ -582,13 +580,15 @@ GUIInputHandler::ProcessSDLEvent(const SDL_Event &e)
|
||||
{
|
||||
int count = 0;
|
||||
if (!uarg_had_digits_ && !uarg_negative_) {
|
||||
// No explicit digits: use current value (default 4 or 4^n)
|
||||
count = (uarg_value_ > 0) ? uarg_value_ : 4;
|
||||
} else {
|
||||
count = uarg_value_;
|
||||
if (uarg_negative_)
|
||||
count = -count;
|
||||
}
|
||||
mi.count = count;
|
||||
mi.count = count;
|
||||
// Clear universal-argument state after applying it
|
||||
uarg_active_ = false;
|
||||
uarg_collecting_ = false;
|
||||
uarg_negative_ = false;
|
||||
|
||||
@@ -77,5 +77,4 @@ k-command mode can be exited with ESC or C-g.
|
||||
|
||||
The find operation is an incremental search. The up or left arrow
|
||||
keys will go to the previous result, while the down or right arrow keys
|
||||
will go to the next result. Unfortunately, the search starts from the
|
||||
top of the file each time. This is a known bug.
|
||||
will go to the next result.
|
||||
@@ -252,9 +252,6 @@ Open using the terminal frontend from kge:
|
||||
(project keybinding manual)
|
||||
.br
|
||||
Project homepage: https://github.com/wntrmute/kte
|
||||
.SH BUGS
|
||||
Report issues on the project tracker. Some behaviors are inherited from
|
||||
ke and may evolve over time; see the manual for notes.
|
||||
.SH AUTHORS
|
||||
Kyle (wntrmute) and contributors.
|
||||
.SH COPYRIGHT
|
||||
|
||||
@@ -279,9 +279,6 @@ Force GUI frontend (if available):
|
||||
(project keybinding manual)
|
||||
.br
|
||||
Project homepage: https://github.com/wntrmute/kte
|
||||
.SH BUGS
|
||||
Incremental search currently restarts from the top on each invocation; see
|
||||
\(lqKnown behavior\(rq in the ke manual. Report issues on the project tracker.
|
||||
.SH AUTHORS
|
||||
Kyle (wntrmute) and contributors.
|
||||
.SH COPYRIGHT
|
||||
|
||||
@@ -39,10 +39,16 @@ public:
|
||||
|
||||
|
||||
// Convenience: load a font by name and size
|
||||
bool LoadFont(const std::string &name, const float size) const
|
||||
bool LoadFont(const std::string &name, const float size)
|
||||
{
|
||||
if (auto *font = Get(name)) {
|
||||
font->Load(size);
|
||||
// Track current selection
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
current_name_ = name;
|
||||
current_size_ = size;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -80,6 +86,21 @@ public:
|
||||
return fonts_.count(name) > 0;
|
||||
}
|
||||
|
||||
|
||||
// Current font name/size as last successfully loaded via LoadFont()
|
||||
std::string CurrentFontName() const
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
return current_name_;
|
||||
}
|
||||
|
||||
|
||||
float CurrentFontSize() const
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
return current_size_;
|
||||
}
|
||||
|
||||
private:
|
||||
FontRegistry() = default;
|
||||
|
||||
@@ -90,6 +111,10 @@ private:
|
||||
bool has_pending_ = false;
|
||||
std::string pending_name_;
|
||||
float pending_size_ = 0.0f;
|
||||
|
||||
// Track last applied font
|
||||
std::string current_name_;
|
||||
float current_size_ = 0.0f;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user