mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-28 07:44:06 +01:00
Logo: adds option logo.position: auto
This commit is contained in:
+97
-18
@@ -26,15 +26,16 @@
|
||||
// 0: title
|
||||
// 1: blank
|
||||
// 2: logo type row
|
||||
// 3: output mode row
|
||||
// 4: blank
|
||||
// 5: modules title row
|
||||
// 6: blank
|
||||
// 7..7+listRows-1: module grid
|
||||
// 7+listRows: description row
|
||||
// 8+listRows: help line 1
|
||||
// 9+listRows: help line 2
|
||||
#define FF_GEN_CONFIG_LIST_TOP 7
|
||||
// 3: logo position row
|
||||
// 4: output mode row
|
||||
// 5: blank
|
||||
// 6: modules title row
|
||||
// 7: blank
|
||||
// 8..8+listRows-1: module grid
|
||||
// 8+listRows: description row
|
||||
// 9+listRows: help line 1
|
||||
// 10+listRows: help line 2
|
||||
#define FF_GEN_CONFIG_LIST_TOP 8
|
||||
#define FF_GEN_CONFIG_BOTTOM_CHROME 3
|
||||
|
||||
// Poll wait timeout (ms) while idle. A longer wait avoids frequent full-screen
|
||||
@@ -66,6 +67,7 @@ typedef struct FFGenConfigUI {
|
||||
uint32_t cursor;
|
||||
uint32_t viewOffset;
|
||||
FFLogoType logoType;
|
||||
FFLogoPosition logoPosition;
|
||||
bool fullConfig;
|
||||
bool confirmingOverwrite;
|
||||
uint16_t rows;
|
||||
@@ -165,7 +167,7 @@ static void enterRawMode(void) {
|
||||
|
||||
static void getTerminalSize(uint16_t* rows, uint16_t* cols) {
|
||||
FFTerminalSizeResult size;
|
||||
if (ffDetectTerminalSize(&size) && size.rows > 0 && size.columns > 0) {
|
||||
if (ffDetectTerminalSize(&size, true) && size.rows > 0 && size.columns > 0) {
|
||||
*rows = size.rows;
|
||||
*cols = size.columns;
|
||||
} else {
|
||||
@@ -248,8 +250,8 @@ static void removeAllBreaksSeparators(FFGenConfigUI* ui) {
|
||||
|
||||
static void computeLayout(FFGenConfigUI* ui) {
|
||||
FFGenConfigLayout* layout = &ui->layout;
|
||||
if (ui->rows < 10) {
|
||||
ui->rows = 10;
|
||||
if (ui->rows < 11) {
|
||||
ui->rows = 11;
|
||||
}
|
||||
int32_t listRows = (int32_t) ui->rows - FF_GEN_CONFIG_LIST_TOP - FF_GEN_CONFIG_BOTTOM_CHROME;
|
||||
layout->listRows = listRows < 0 ? 0 : (uint16_t) listRows;
|
||||
@@ -367,6 +369,26 @@ static void cycleLogoType(FFGenConfigUI* ui, int delta) {
|
||||
}
|
||||
}
|
||||
|
||||
static void cycleLogoPosition(FFGenConfigUI* ui, int delta) {
|
||||
static const FFLogoPosition positions[] = {
|
||||
FF_LOGO_POSITION_AUTO,
|
||||
FF_LOGO_POSITION_LEFT,
|
||||
FF_LOGO_POSITION_RIGHT,
|
||||
FF_LOGO_POSITION_TOP,
|
||||
};
|
||||
|
||||
uint32_t index = 0;
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(positions); ++i) {
|
||||
if (positions[i] == ui->logoPosition) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
index = (index + (delta > 0 ? 1 : ARRAY_SIZE(positions) - 1)) % ARRAY_SIZE(positions);
|
||||
ui->logoPosition = positions[index];
|
||||
}
|
||||
|
||||
static uint32_t countSelectedModules(const FFlist* items) {
|
||||
uint32_t count = 0;
|
||||
FF_LIST_FOR_EACH (FFGenConfigItem, item, *items) {
|
||||
@@ -558,7 +580,46 @@ static void renderFrame(FFGenConfigUI* ui, FFstrbuf* out) {
|
||||
}
|
||||
finishRow(&row, out, ++rowCount == ui->rows);
|
||||
|
||||
// Row 3: output mode
|
||||
// Row 3: logo position
|
||||
rowInit(&row, cols);
|
||||
rowAppendVisual(&row, " ");
|
||||
rowAppendRaw(&row, "\e[" FF_COLOR_MODE_BOLD "m");
|
||||
rowAppendVisual(&row, "Logo ");
|
||||
rowAppendRaw(&row, "\e[" FF_COLOR_MODE_UNDERLINE_ "m");
|
||||
rowAppendVisual(&row, "p");
|
||||
rowAppendRaw(&row, "\e[24m"); // Reset underline
|
||||
rowAppendVisual(&row, "osition:");
|
||||
rowAppendRaw(&row, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
rowAppendVisual(&row, " ");
|
||||
drawLogoOption(&row, "auto", ui->logoPosition == FF_LOGO_POSITION_AUTO);
|
||||
rowAppendVisual(&row, " ");
|
||||
drawLogoOption(&row, "left", ui->logoPosition == FF_LOGO_POSITION_LEFT);
|
||||
rowAppendVisual(&row, " ");
|
||||
drawLogoOption(&row, "right", ui->logoPosition == FF_LOGO_POSITION_RIGHT);
|
||||
rowAppendVisual(&row, " ");
|
||||
drawLogoOption(&row, "top", ui->logoPosition == FF_LOGO_POSITION_TOP);
|
||||
if (cols >= 120) {
|
||||
rowAppendRaw(&row, FASTFETCH_TEXT_MODIFIER_SOFT);
|
||||
switch (ui->logoPosition) {
|
||||
case FF_LOGO_POSITION_AUTO:
|
||||
rowAppendVisual(&row, " - Choose left or top from terminal width");
|
||||
break;
|
||||
case FF_LOGO_POSITION_RIGHT:
|
||||
rowAppendVisual(&row, " - Place the logo to the right");
|
||||
break;
|
||||
case FF_LOGO_POSITION_TOP:
|
||||
rowAppendVisual(&row, " - Place the logo above module output");
|
||||
break;
|
||||
case FF_LOGO_POSITION_LEFT:
|
||||
default:
|
||||
rowAppendVisual(&row, " - Place the logo to the left");
|
||||
break;
|
||||
}
|
||||
rowAppendRaw(&row, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
}
|
||||
finishRow(&row, out, ++rowCount == ui->rows);
|
||||
|
||||
// Row 4: output mode
|
||||
rowInit(&row, cols);
|
||||
rowAppendVisual(&row, " ");
|
||||
rowAppendRaw(&row, "\e[" FF_COLOR_MODE_BOLD FF_COLOR_MODE_UNDERLINE_ "m");
|
||||
@@ -581,11 +642,11 @@ static void renderFrame(FFGenConfigUI* ui, FFstrbuf* out) {
|
||||
}
|
||||
finishRow(&row, out, ++rowCount == ui->rows);
|
||||
|
||||
// Row 4: blank
|
||||
// Row 5: blank
|
||||
rowInit(&row, cols);
|
||||
finishRow(&row, out, ++rowCount == ui->rows);
|
||||
|
||||
// Row 5: modules title
|
||||
// Row 6: modules title
|
||||
rowInit(&row, cols);
|
||||
rowAppendVisual(&row, " ");
|
||||
rowAppendRaw(&row, FASTFETCH_TEXT_MODIFIER_BOLT);
|
||||
@@ -596,7 +657,7 @@ static void renderFrame(FFGenConfigUI* ui, FFstrbuf* out) {
|
||||
rowAppendRaw(&row, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
finishRow(&row, out, ++rowCount == ui->rows);
|
||||
|
||||
// Row 6: blank
|
||||
// Row 7: blank
|
||||
rowInit(&row, cols);
|
||||
finishRow(&row, out, ++rowCount == ui->rows);
|
||||
|
||||
@@ -618,7 +679,7 @@ static void renderFrame(FFGenConfigUI* ui, FFstrbuf* out) {
|
||||
finishRow(&row, out, ++rowCount == ui->rows);
|
||||
}
|
||||
|
||||
// Row after grid: description
|
||||
// Row 9+listRows: description
|
||||
rowInit(&row, cols);
|
||||
if (ui->cursor < ui->items.length) {
|
||||
const FFGenConfigItem* item = FF_LIST_GET(FFGenConfigItem, ui->items, ui->cursor);
|
||||
@@ -650,7 +711,7 @@ static void renderFrame(FFGenConfigUI* ui, FFstrbuf* out) {
|
||||
|
||||
rowInit(&row, cols);
|
||||
rowAppendRaw(&row, "\e[" FF_COLOR_MODE_DIM_ "m");
|
||||
rowAppendVisual(&row, " l/L logo o minimal/full s/Enter save q/Esc quit g/G top/bottom");
|
||||
rowAppendVisual(&row, " l/L logo p/P position o minimal/full s/Enter save q/Esc quit g/G top/bottom");
|
||||
rowAppendRaw(&row, FASTFETCH_TEXT_MODIFIER_RESET);
|
||||
finishRow(&row, out, ++rowCount == ui->rows);
|
||||
|
||||
@@ -904,6 +965,10 @@ static int handleKey(FFGenConfigUI* ui, FFGenConfigKey key, char ch, bool fileEx
|
||||
cycleLogoType(ui, 1);
|
||||
} else if (ch == 'L') {
|
||||
cycleLogoType(ui, -1);
|
||||
} else if (ch == 'p') {
|
||||
cycleLogoPosition(ui, 1);
|
||||
} else if (ch == 'P') {
|
||||
cycleLogoPosition(ui, -1);
|
||||
} else if (ch == '\x03' || ch == '\x04' || ch == '\x1a' || ch == '\x1c') {
|
||||
return 0;
|
||||
}
|
||||
@@ -940,6 +1005,18 @@ static FFLogoType initialLogoType(void) {
|
||||
}
|
||||
}
|
||||
|
||||
static FFLogoPosition initialLogoPosition(void) {
|
||||
switch (instance.config.logo.position) {
|
||||
case FF_LOGO_POSITION_TOP:
|
||||
case FF_LOGO_POSITION_RIGHT:
|
||||
case FF_LOGO_POSITION_AUTO:
|
||||
return instance.config.logo.position;
|
||||
case FF_LOGO_POSITION_LEFT:
|
||||
default:
|
||||
return FF_LOGO_POSITION_LEFT;
|
||||
}
|
||||
}
|
||||
|
||||
static bool applyConfig(FFdata* data, const FFlist* items, bool fullConfig) {
|
||||
if (data->resultDoc) {
|
||||
fputs("Error: duplicated `--gen-config` or `--format json` flags found\n", stderr);
|
||||
@@ -972,6 +1049,7 @@ bool ffGenConfigInteractive(FFdata* data) {
|
||||
.cursor = 0,
|
||||
.viewOffset = 0,
|
||||
.logoType = initialLogoType(),
|
||||
.logoPosition = initialLogoPosition(),
|
||||
.fullConfig = false,
|
||||
.confirmingOverwrite = false,
|
||||
.rows = 24,
|
||||
@@ -993,6 +1071,7 @@ bool ffGenConfigInteractive(FFdata* data) {
|
||||
if (result == 1) {
|
||||
if (applyConfig(data, &ui.items, ui.fullConfig)) {
|
||||
instance.config.logo.type = ui.logoType;
|
||||
instance.config.logo.position = ui.logoPosition;
|
||||
success = true;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -10,4 +10,5 @@ typedef struct FFTerminalSizeResult {
|
||||
uint16_t height;
|
||||
} FFTerminalSizeResult;
|
||||
|
||||
bool ffDetectTerminalSize(FFTerminalSizeResult* result);
|
||||
// `fastOnly` avoids terminal query/response sequences and is intended for startup layout decisions.
|
||||
bool ffDetectTerminalSize(FFTerminalSizeResult* result, bool fastOnly);
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
#include <sys/termios.h>
|
||||
#endif
|
||||
|
||||
bool ffDetectTerminalSize(FFTerminalSizeResult* result) {
|
||||
bool ffDetectTerminalSize(FFTerminalSizeResult* result, bool fastOnly) {
|
||||
*result = (FFTerminalSizeResult){};
|
||||
|
||||
struct winsize winsize = {};
|
||||
static int ttyfd = STDOUT_FILENO;
|
||||
if (!isatty(ttyfd)) {
|
||||
@@ -18,21 +20,20 @@ bool ffDetectTerminalSize(FFTerminalSizeResult* result) {
|
||||
|
||||
ioctl(ttyfd, TIOCGWINSZ, &winsize);
|
||||
|
||||
if (winsize.ws_row == 0 || winsize.ws_col == 0) {
|
||||
ffGetTerminalResponse("\e[18t", 2, "\e[8;%hu;%hut", &winsize.ws_row, &winsize.ws_col);
|
||||
}
|
||||
if (!fastOnly) {
|
||||
if (winsize.ws_row == 0 || winsize.ws_col == 0) {
|
||||
ffGetTerminalResponse("\e[18t", 2, "\e[8;%hu;%hut", &winsize.ws_row, &winsize.ws_col);
|
||||
}
|
||||
|
||||
if (winsize.ws_ypixel == 0 || winsize.ws_xpixel == 0) {
|
||||
ffGetTerminalResponse("\e[14t", 2, "\e[4;%hu;%hut", &winsize.ws_ypixel, &winsize.ws_xpixel);
|
||||
}
|
||||
|
||||
if (winsize.ws_row == 0 && winsize.ws_col == 0) {
|
||||
return false;
|
||||
if (winsize.ws_ypixel == 0 || winsize.ws_xpixel == 0) {
|
||||
ffGetTerminalResponse("\e[14t", 2, "\e[4;%hu;%hut", &winsize.ws_ypixel, &winsize.ws_xpixel);
|
||||
}
|
||||
}
|
||||
|
||||
result->rows = winsize.ws_row;
|
||||
result->columns = winsize.ws_col;
|
||||
result->width = winsize.ws_xpixel;
|
||||
result->height = winsize.ws_ypixel;
|
||||
return true;
|
||||
|
||||
return result->rows > 0 && result->columns > 0;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
bool ffDetectTerminalSize(FFTerminalSizeResult* result) {
|
||||
bool ffDetectTerminalSize(FFTerminalSizeResult* result, bool fastOnly) {
|
||||
*result = (FFTerminalSizeResult){};
|
||||
|
||||
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
FF_AUTO_CLOSE_FD HANDLE hConout = INVALID_HANDLE_VALUE;
|
||||
{
|
||||
@@ -18,16 +20,20 @@ bool ffDetectTerminalSize(FFTerminalSizeResult* result) {
|
||||
if (GetConsoleScreenBufferInfo(hOutput, &csbi)) {
|
||||
result->columns = (uint16_t) (csbi.srWindow.Right - csbi.srWindow.Left + 1);
|
||||
result->rows = (uint16_t) (csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
|
||||
} else {
|
||||
} else if (!fastOnly) {
|
||||
// Windows Terminal doesn't report `\e` for some reason
|
||||
ffGetTerminalResponse("\e[18t", 2, "%*[^;];%hu;%hut", &result->rows, &result->columns);
|
||||
}
|
||||
}
|
||||
|
||||
if (result->columns == 0 && result->rows == 0) {
|
||||
if (result->columns == 0 || result->rows == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fastOnly) {
|
||||
return true;
|
||||
}
|
||||
|
||||
{
|
||||
CONSOLE_FONT_INFOEX cfi = { .cbSize = sizeof(cfi) };
|
||||
if (GetCurrentConsoleFontEx(hOutput, FALSE, &cfi)) // Only works for ConHost
|
||||
@@ -41,5 +47,5 @@ bool ffDetectTerminalSize(FFTerminalSizeResult* result) {
|
||||
}
|
||||
}
|
||||
|
||||
return result->columns > 0 && result->rows > 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
+9
-2
@@ -854,9 +854,16 @@ static void writeConfigFile(FFdata* data) {
|
||||
} else if (data->genConfigInteractive) {
|
||||
if (instance.config.logo.type == FF_LOGO_TYPE_NONE) {
|
||||
yyjson_mut_obj_add_null(doc, root, "logo");
|
||||
} else if (instance.config.logo.type == FF_LOGO_TYPE_SMALL) {
|
||||
} else if (instance.config.logo.type == FF_LOGO_TYPE_SMALL && instance.config.logo.position == FF_LOGO_POSITION_LEFT) {
|
||||
yyjson_mut_obj_add_str(doc, root, "logo", "small");
|
||||
} else if (instance.config.logo.position != FF_LOGO_POSITION_LEFT || instance.config.logo.type == FF_LOGO_TYPE_SMALL) {
|
||||
yyjson_mut_val* logo = yyjson_mut_obj(doc);
|
||||
yyjson_mut_obj_add_str(doc, logo, "type", "small");
|
||||
if (instance.config.logo.type == FF_LOGO_TYPE_SMALL) {
|
||||
yyjson_mut_obj_add_str(doc, logo, "type", "small");
|
||||
}
|
||||
if (instance.config.logo.position != FF_LOGO_POSITION_LEFT) {
|
||||
yyjson_mut_obj_add_str(doc, logo, "position", ffLogoPositionToString(instance.config.logo.position));
|
||||
}
|
||||
yyjson_mut_obj_add_val(doc, root, "logo", logo);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-1
@@ -20,6 +20,11 @@
|
||||
#include <sys/termios.h>
|
||||
#endif
|
||||
|
||||
static void resolveImageAutoPosition(uint32_t logoWidth) {
|
||||
const FFOptionsLogo* options = &instance.config.logo;
|
||||
ffLogoResolveAutoPosition(logoWidth + options->paddingLeft + options->paddingRight);
|
||||
}
|
||||
|
||||
static bool printImageIterm(bool printError) {
|
||||
const FFOptionsLogo* options = &instance.config.logo;
|
||||
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
|
||||
@@ -633,6 +638,7 @@ static void printImagePixelsNoCache(FFLogoRequestData* requestData, const FFstrb
|
||||
static void fillCharacterDimensions(FFLogoRequestData* requestData) {
|
||||
requestData->logoCharacterWidth = (uint32_t) ceil((double) requestData->logoPixelWidth / requestData->characterPixelWidth);
|
||||
requestData->logoCharacterHeight = (uint32_t) ceil((double) requestData->logoPixelHeight / requestData->characterPixelHeight);
|
||||
resolveImageAutoPosition(requestData->logoCharacterWidth);
|
||||
}
|
||||
|
||||
static bool printImageSixel(FFLogoRequestData* requestData, const FFstrbuf* result) {
|
||||
@@ -1515,6 +1521,8 @@ static bool printCachedPixel(FFLogoRequestData* requestData) {
|
||||
}
|
||||
}
|
||||
|
||||
resolveImageAutoPosition(requestData->logoCharacterWidth);
|
||||
|
||||
if (requestData->type == FF_LOGO_TYPE_IMAGE_KITTY &&
|
||||
options->animationFrame == FF_LOGO_ANIMATION_FRAME_ANIMATE) {
|
||||
// An animation entry holds payloads, not an envelope, so it can not be streamed out like
|
||||
@@ -1610,7 +1618,7 @@ static bool getCharacterPixelDimensions(FFLogoRequestData* requestData) {
|
||||
#endif
|
||||
|
||||
FFTerminalSizeResult termSize = {};
|
||||
if (ffDetectTerminalSize(&termSize)) {
|
||||
if (ffDetectTerminalSize(&termSize, false)) {
|
||||
requestData->characterPixelWidth = termSize.width / (double) termSize.columns;
|
||||
requestData->characterPixelHeight = termSize.height / (double) termSize.rows;
|
||||
}
|
||||
@@ -1773,14 +1781,17 @@ bool ffLogoPrintImageIfExists(FFLogoType type, bool printError) {
|
||||
}
|
||||
|
||||
if (type == FF_LOGO_TYPE_IMAGE_ITERM) {
|
||||
resolveImageAutoPosition(instance.config.logo.width);
|
||||
return printImageIterm(printError);
|
||||
}
|
||||
|
||||
if (type == FF_LOGO_TYPE_IMAGE_KITTY_DIRECT) {
|
||||
resolveImageAutoPosition(instance.config.logo.width);
|
||||
return printImageKittyDirect(printError);
|
||||
}
|
||||
|
||||
if (type == FF_LOGO_TYPE_IMAGE_KITTY_ICAT) {
|
||||
resolveImageAutoPosition(instance.config.logo.width);
|
||||
return printImageKittyIcat(printError);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "detection/media/media.h"
|
||||
#include "detection/os/os.h"
|
||||
#include "detection/terminalshell/terminalshell.h"
|
||||
#include "detection/terminalsize/terminalsize.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
@@ -17,6 +18,37 @@ typedef struct FFLogoCachedLine {
|
||||
uint32_t width;
|
||||
} FFLogoCachedLine;
|
||||
|
||||
FFLogoPosition ffLogoSelectPosition(FFLogoPosition configured, uint32_t terminalColumns, uint32_t logoWidth) {
|
||||
if (configured != FF_LOGO_POSITION_AUTO) {
|
||||
return configured;
|
||||
}
|
||||
|
||||
if (terminalColumns == 0) {
|
||||
return FF_LOGO_POSITION_LEFT;
|
||||
}
|
||||
|
||||
return logoWidth <= terminalColumns && terminalColumns - logoWidth >= FF_LOGO_AUTO_MIN_INFO_WIDTH
|
||||
? FF_LOGO_POSITION_LEFT
|
||||
: FF_LOGO_POSITION_TOP;
|
||||
}
|
||||
|
||||
void ffLogoResolveAutoPosition(uint32_t logoWidth) {
|
||||
FFOptionsLogo* options = &instance.config.logo;
|
||||
if (options->position != FF_LOGO_POSITION_AUTO) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t terminalColumns = 0;
|
||||
if (ffIsTerminal(STDOUT_FILENO)) {
|
||||
FFTerminalSizeResult size = {};
|
||||
if (ffDetectTerminalSize(&size, true)) {
|
||||
terminalColumns = size.columns;
|
||||
}
|
||||
}
|
||||
|
||||
options->position = ffLogoSelectPosition(FF_LOGO_POSITION_AUTO, terminalColumns, logoWidth);
|
||||
}
|
||||
|
||||
static void logoLineCacheClear(FFLogoLineCacheState* cache) {
|
||||
FF_LIST_FOR_EACH (FFLogoCachedLine, line, cache->lines) {
|
||||
ffStrbufDestroy(&line->chars);
|
||||
@@ -175,6 +207,8 @@ static void logoLineCacheBuild(FFLogoLineCacheState* cache, const char* data, bo
|
||||
parsedHeight = options->height;
|
||||
}
|
||||
|
||||
ffLogoResolveAutoPosition(maxLineWidth + options->paddingRight);
|
||||
|
||||
instance.state.logoHeight = options->paddingTop + parsedHeight;
|
||||
if (options->position == FF_LOGO_POSITION_LEFT) {
|
||||
instance.state.logoWidth = maxLineWidth + options->paddingRight;
|
||||
@@ -195,6 +229,8 @@ static bool ffLogoPrintCharsRaw(const char* data, size_t length, bool printError
|
||||
FFOptionsLogo* options = &instance.config.logo;
|
||||
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
|
||||
|
||||
ffLogoResolveAutoPosition(options->width + options->paddingLeft + options->paddingRight);
|
||||
|
||||
if (!options->width || !options->height) {
|
||||
if (options->position == FF_LOGO_POSITION_LEFT) {
|
||||
ffStrbufAppendF(&buf, "\e[2J\e[3J\e[%u;%uH", (unsigned) options->paddingTop + 1, (unsigned) options->paddingLeft + 1);
|
||||
|
||||
@@ -24,6 +24,10 @@ typedef struct FFlogo {
|
||||
} FFlogo;
|
||||
|
||||
// logo.c
|
||||
enum { FF_LOGO_AUTO_MIN_INFO_WIDTH = 32 };
|
||||
|
||||
FFLogoPosition ffLogoSelectPosition(FFLogoPosition configured, uint32_t terminalColumns, uint32_t logoWidth);
|
||||
void ffLogoResolveAutoPosition(uint32_t logoWidth);
|
||||
void ffLogoPrint(void);
|
||||
void ffLogoPrintChars(const char* data, bool doColorReplacement);
|
||||
void ffLogoPrintLine(void);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
bool ffPrintTerminalSize(FFTerminalSizeOptions* options) {
|
||||
FFTerminalSizeResult result = {};
|
||||
|
||||
if (!ffDetectTerminalSize(&result)) {
|
||||
if (!ffDetectTerminalSize(&result, false)) {
|
||||
ffPrintError(FF_MODULE_GET_DISPLAY_NAME(TerminalSize), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Failed to detect terminal size");
|
||||
return false;
|
||||
}
|
||||
@@ -51,7 +51,7 @@ void ffGenerateTerminalSizeJsonConfig(FFTerminalSizeOptions* options, yyjson_mut
|
||||
bool ffGenerateTerminalSizeJsonResult([[maybe_unused]] FFTerminalSizeOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) {
|
||||
FFTerminalSizeResult result;
|
||||
|
||||
if (!ffDetectTerminalSize(&result)) {
|
||||
if (!ffDetectTerminalSize(&result, false)) {
|
||||
yyjson_mut_obj_add_str(doc, module, "error", "Failed to detect terminal size");
|
||||
return false;
|
||||
}
|
||||
|
||||
+17
-5
@@ -39,6 +39,20 @@ static void logoParseImageFlag(FFOptionsLogo* options, const char* key, const ch
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* ffLogoPositionToString(FFLogoPosition position) {
|
||||
switch (position) {
|
||||
case FF_LOGO_POSITION_TOP:
|
||||
return "top";
|
||||
case FF_LOGO_POSITION_RIGHT:
|
||||
return "right";
|
||||
case FF_LOGO_POSITION_AUTO:
|
||||
return "auto";
|
||||
case FF_LOGO_POSITION_LEFT:
|
||||
default:
|
||||
return "left";
|
||||
}
|
||||
}
|
||||
|
||||
void ffOptionsInitLogo(FFOptionsLogo* options) {
|
||||
ffStrbufInit(&options->source);
|
||||
options->type = FF_LOGO_TYPE_AUTO;
|
||||
@@ -162,6 +176,7 @@ bool ffOptionsParseLogoCommandLine(FFOptionsLogo* options, const char* key, cons
|
||||
exit(477);
|
||||
} else if (ffStrEqualsIgnCase(subKey, "position")) {
|
||||
options->position = (FFLogoPosition) ffOptionParseEnum(key, value, (FFKeyValuePair[]) {
|
||||
{ "auto", FF_LOGO_POSITION_AUTO },
|
||||
{ "left", FF_LOGO_POSITION_LEFT },
|
||||
{ "right", FF_LOGO_POSITION_RIGHT },
|
||||
{ "top", FF_LOGO_POSITION_TOP },
|
||||
@@ -403,6 +418,7 @@ const char* ffOptionsParseLogoJsonConfig(FFOptionsLogo* options, yyjson_val* roo
|
||||
} else if (unsafe_yyjson_equals_str(key, "position")) {
|
||||
int value;
|
||||
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
|
||||
{ "auto", FF_LOGO_POSITION_AUTO },
|
||||
{ "left", FF_LOGO_POSITION_LEFT },
|
||||
{ "top", FF_LOGO_POSITION_TOP },
|
||||
{ "right", FF_LOGO_POSITION_RIGHT },
|
||||
@@ -604,11 +620,7 @@ void ffOptionsGenerateLogoJsonConfig(FFdata* data, FFOptionsLogo* options) {
|
||||
break;
|
||||
}
|
||||
|
||||
yyjson_mut_obj_add_str(doc, obj, "position", ((const char*[]) {
|
||||
"left",
|
||||
"top",
|
||||
"right",
|
||||
})[options->position]);
|
||||
yyjson_mut_obj_add_str(doc, obj, "position", ffLogoPositionToString(options->position));
|
||||
|
||||
yyjson_mut_obj_add_int(doc, obj, "animationFrame", options->animationFrame);
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ typedef enum FFLogoPosition: uint8_t {
|
||||
FF_LOGO_POSITION_LEFT,
|
||||
FF_LOGO_POSITION_TOP,
|
||||
FF_LOGO_POSITION_RIGHT,
|
||||
FF_LOGO_POSITION_AUTO,
|
||||
} FFLogoPosition;
|
||||
|
||||
typedef enum FFLogoCacheStrategy: uint8_t {
|
||||
@@ -70,6 +71,7 @@ typedef struct FFOptionsLogo {
|
||||
#endif
|
||||
} FFOptionsLogo;
|
||||
|
||||
const char* ffLogoPositionToString(FFLogoPosition position);
|
||||
void ffOptionsInitLogo(FFOptionsLogo* options);
|
||||
bool ffOptionsParseLogoCommandLine(FFOptionsLogo* options, const char* key, const char* value);
|
||||
void ffOptionsDestroyLogo(FFOptionsLogo* options);
|
||||
|
||||
Reference in New Issue
Block a user