Compare commits

..

No commits in common. "e957bba771ea200da16f4d3a02aaec7784c65168" and "caba65b2bcf7972ab41669bb6bbcc1c5928d673e" have entirely different histories.

2 changed files with 24 additions and 41 deletions

View File

@ -1,4 +1,4 @@
Copyright (c) 2016 - 2018, Přemysl Janouch <p@janouch.name> Copyright (c) 2016 - 2017, Přemysl Janouch <p@janouch.name>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted. purpose with or without fee is hereby granted.

View File

@ -1,7 +1,7 @@
/* /*
* nncmpp -- the MPD client you never knew you needed * nncmpp -- the MPD client you never knew you needed
* *
* Copyright (c) 2016 - 2018, Přemysl Janouch <p@janouch.name> * Copyright (c) 2016 - 2017, Přemysl Janouch <p@janouch.name>
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted. * purpose with or without fee is hereby granted.
@ -66,7 +66,6 @@ enum
#include "liberty/liberty.c" #include "liberty/liberty.c"
#include "liberty/liberty-tui.c" #include "liberty/liberty-tui.c"
#include <math.h>
#include <locale.h> #include <locale.h>
#include <termios.h> #include <termios.h>
#ifndef TIOCGWINSZ #ifndef TIOCGWINSZ
@ -1172,34 +1171,6 @@ app_visible_items (void)
return MAX (0, app_fitting_items ()); return MAX (0, app_fitting_items ());
} }
/// Figure out scrollbar appearance. @a s is the minimal slider length as well
/// as the scrollbar resolution per @a visible item.
struct scrollbar { long length, start; }
app_compute_scrollbar (struct tab *tab, long visible, long s)
{
long top = tab->item_top, total = tab->item_count;
if (total < visible)
return (struct scrollbar) { 0, 0 };
if (visible == 1)
return (struct scrollbar) { s, 0 };
if (visible == 2)
return (struct scrollbar) { s, top >= total / 2 ? s : 0 };
// Only be at the top or bottom when the top or bottom item can be seen.
// The algorithm isn't optimal but it's a bitch to get right.
double available_length = s * visible - 2 - s + 1;
double lenf = s + available_length * visible / total, length = 0.;
long offset = 1 + available_length * top / total + modf (lenf, &length);
if (top == 0)
return (struct scrollbar) { length, 0 };
if (top + visible >= total)
return (struct scrollbar) { length, s * visible - length };
return (struct scrollbar) { length, offset };
}
static void static void
app_draw_scrollbar (void) app_draw_scrollbar (void)
{ {
@ -1212,14 +1183,18 @@ app_draw_scrollbar (void)
struct tab *tab = g.active_tab; struct tab *tab = g.active_tab;
int visible_items = app_visible_items (); int visible_items = app_visible_items ();
hard_assert (tab->item_count != 0);
if (!g.use_partial_boxes) if (!g.use_partial_boxes)
{ {
struct scrollbar bar = app_compute_scrollbar (tab, visible_items, 1); // Apparently here we don't want the 0.5 rounding constant
int length = (float) visible_items / (int) tab->item_count
* (visible_items - 1);
int start = (float) tab->item_top / (int) tab->item_count
* (visible_items - 1);
for (int row = 0; row < visible_items; row++) for (int row = 0; row < visible_items; row++)
{ {
move (g.header_height + row, COLS - 1); move (g.header_height + row, COLS - 1);
if (row < bar.start || row >= bar.start + bar.length) if (row < start || row > start + length + 1)
addch (' ' | APP_ATTR (SCROLLBAR)); addch (' ' | APP_ATTR (SCROLLBAR));
else else
addch (' ' | APP_ATTR (SCROLLBAR) | A_REVERSE); addch (' ' | APP_ATTR (SCROLLBAR) | A_REVERSE);
@ -1227,11 +1202,19 @@ app_draw_scrollbar (void)
return; return;
} }
struct scrollbar bar = app_compute_scrollbar (tab, visible_items, 8); // TODO: clamp the values, make sure they follow the right order
bar.length += bar.start; // We subtract half a character from both the top and the bottom, hence -1
// XXX: I'm not completely sure why we need that 0.5 constant in both
int length = (double) visible_items / tab->item_count
* (visible_items - 1) * 8 + 0.5;
int start = (double) tab->item_top / tab->item_count
* (visible_items - 1) * 8 + 0.5;
int start_part = bar.start % 8; bar.start /= 8; // Then we make sure the bar is at least one character high, hence +8
int end_part = bar.length % 8; bar.length /= 8; int end = start + length + 8;
int start_part = start % 8; start /= 8;
int end_part = end % 8; end /= 8;
// Even with this, the solid part must be at least one character high // Even with this, the solid part must be at least one character high
static const char *partials[] = { "", "", "", "", "", "", "", "" }; static const char *partials[] = { "", "", "", "", "", "", "", "" };
@ -1239,12 +1222,12 @@ app_draw_scrollbar (void)
for (int row = 0; row < visible_items; row++) for (int row = 0; row < visible_items; row++)
{ {
chtype attrs = APP_ATTR (SCROLLBAR); chtype attrs = APP_ATTR (SCROLLBAR);
if (row > bar.start && row <= bar.length) if (row > start && row <= end)
attrs ^= A_REVERSE; attrs ^= A_REVERSE;
const char *c = " "; const char *c = " ";
if (row == bar.start) c = partials[start_part]; if (row == start) c = partials[start_part];
if (row == bar.length) c = partials[end_part]; if (row == end) c = partials[end_part];
move (g.header_height + row, COLS - 1); move (g.header_height + row, COLS - 1);