Skip to content

Commit

Permalink
'Cut in the middle' feature to easy distinguish filenames that are to…
Browse files Browse the repository at this point in the history
…o long to be displayed fully in the OSD, but have same starting characters. Done by calculating filename differs with neighbouring filenames in the filename list.
  • Loading branch information
theypsilon committed Jan 11, 2020
1 parent 85b677a commit 60ea22a
Showing 1 changed file with 98 additions and 20 deletions.
118 changes: 98 additions & 20 deletions menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5018,11 +5018,67 @@ void PrintFileName(char *name, int row, int maxinv)
OsdWrite(row, s, 1, 0, 0, maxinv);
}

// Choosed number to place the '...' cut in the middle of the displayed filename.
// Since total filename chars in display during a too long filename situation is 27.
// the maths would be 12 from beginning + 3 from the cut + 12 from the ending.
const int CUT_IN_MIDDLE_ENDING_LEN = 12;

static int find_pos_where_they_differ(const char* a, const char* b) {
for (int i = 0; a[i] != '\0' && b[i] != '\0'; i++) {
if (a[i] != b[i]) {
int j; // backtracking to find the beginning of the word where 'a' and 'b' differ.
for (j = i - 1; j >= 0 && a[j] != ' '; j--);
j++; // but place the position where a word has already started.
if (j > 0 && (i - j) <= CUT_IN_MIDDLE_ENDING_LEN) {
return j;
} else {
// If the word where they differ is too long, we ignore it when returing differ position.
return i;
}
}
}
return -1;
}

static const char* get_fixed_altname(direntext_t* diritem, int* len) {
const char* altname;
int offset;
if((diritem->de.d_type == DT_DIR) && (fs_Options & SCANO_CORES) && (diritem->altname[0] == '_')) {
// If a dir starts with '_', we don't display the '_' and we fix the length.
altname = diritem->altname + 1;
if (len) {
*len += 1;
}
} else {
altname = diritem->altname;
}
return altname;
}

static void strncpy_with_cut_in_middle(char* s, const char* altname, int altname_len, int differ_pos) {
int ending = CUT_IN_MIDDLE_ENDING_LEN;
if (ending + differ_pos > altname_len) {
ending = altname_len - differ_pos;
}
strncpy(s, altname, 27 - ending - 3);
strncpy(s + 27 - ending - 3, "...", 3);
strncpy(s + 27 - ending, altname + differ_pos, ending);
}

static int min(int a, int b) {
return a > b ? b : a;
}

// print directory contents
void PrintDirectory(void)
{
int k;
int len;
int direntry;
direntext_t* diritem = nullptr;
const char* altname = nullptr;
int altname_len;

int cur_differ_pos = -1;
int prev_differ_pos = -1;

char s[40];
ScrollReset();
Expand All @@ -5035,33 +5091,54 @@ void PrintDirectory(void)

if (i < flist_nDirEntries())
{
k = flist_iFirstEntry() + i;
len = strlen(flist_DirItem(k)->altname); // get name length
direntry = flist_iFirstEntry() + i;
diritem = flist_DirItem(direntry);
altname_len = strlen(diritem->altname); // get name length

const char *datecode = 0;
if (flist_DirItem(k)->de.d_type != DT_DIR) // if a file
if (diritem->de.d_type != DT_DIR) // if a file
{
len = calc_name_length(flist_DirItem(k)->altname, fs_pFileExt, &datecode);
altname_len = calc_name_length(diritem->altname, fs_pFileExt, &datecode);
}

if (len > 28)
altname = get_fixed_altname(diritem, &altname_len);

bool is_name_too_long = altname_len > 28; // too long means that the full filename does not fit inside the view size of the OSD.
if (is_name_too_long)
{
len = 27; // trim display length if longer than 30 characters
s[28] = 22;
s[28] = 22; // display symbol at the end of the line, indicating name is not fully displayed.
}

if((flist_DirItem(k)->de.d_type == DT_DIR) && (fs_Options & SCANO_CORES) && (flist_DirItem(k)->altname[0] == '_'))
{
strncpy(s + 1, flist_DirItem(k)->altname+1, len-1);
if ((i + 1) < flist_nDirEntries() && is_name_too_long) {
// fetching the filename of the next direntry
const char* next_altname = get_fixed_altname(flist_DirItem(flist_iFirstEntry() + i + 1), nullptr);
// we get the position where the current filename and the next filename differ
cur_differ_pos = find_pos_where_they_differ(altname, next_altname);
} else {
cur_differ_pos = -1;
}
else
{
strncpy(s + 1, flist_DirItem(k)->altname, len); // display only name

// If we've differed with the previous filename, or if we differ with the next filename in a position out of sight for the OSD:
if (prev_differ_pos > 28 || cur_differ_pos > 28) {
int differ_pos;
int min_differ = min(cur_differ_pos, prev_differ_pos);
if (min_differ > 28) {
differ_pos = min_differ;
} else if (prev_differ_pos > 28) {
differ_pos = prev_differ_pos;
} else {
differ_pos = cur_differ_pos;
}
strncpy_with_cut_in_middle(s + 1, altname, altname_len, differ_pos);
} else {
strncpy(s + 1, altname, is_name_too_long ? 27 : altname_len); // display only name, trimmed names are 27 chars long, because char 28 is for the symbol indicating name is not fully displayed.
}

if (flist_DirItem(k)->de.d_type == DT_DIR) // mark directory with suffix
prev_differ_pos = cur_differ_pos;

if (diritem->de.d_type == DT_DIR) // mark directory with suffix
{
if (!strcmp(flist_DirItem(k)->altname, ".."))
if (!strcmp(altname, ".."))
{
strcpy(&s[19], " <UP-DIR>");
}
Expand All @@ -5083,15 +5160,16 @@ void PrintDirectory(void)
s[n++] = datecode[4];
s[n++] = datecode[5];

if (len >= 19)
if (altname_len >= 19)
{
s[19] = 22;
s[28] = ' ';
}
}

if (!i && k) leftchar = 17;
if ((i == OsdGetSize() - 1) && (k < flist_nDirEntries() - 1)) leftchar = 16;
if (!i && direntry) leftchar = 17;
if ((i == OsdGetSize() - 1) && (direntry < flist_nDirEntries() - 1)) leftchar = 16;

}
else
{
Expand Down

0 comments on commit 60ea22a

Please sign in to comment.